From 0b0c8734f35227d910cd1d25e6ed94d8e0cc208c Mon Sep 17 00:00:00 2001 From: stephan Date: Sun, 28 Sep 2025 00:53:00 +0000 Subject: [PATCH] Improve #if support in, and add #assert to, c-pp. Rename target=... preprocessor symbols to target:... because changes in the semantics for symbols which have an '=' makes some of those #if blocks mutually exclusive (which we won't want in rare cases involving the bundler-friendly builds). FossilOrigin-Name: 54287487793d48f6dde919446ab7476aea0cc0aba3835c80f060a7b84221881a --- ext/wasm/GNUmakefile | 8 +- ext/wasm/api/extern-post-js.c-pp.js | 8 +- ext/wasm/api/pre-js.c-pp.js | 4 +- ext/wasm/api/sqlite3-vfs-opfs-sahpool.c-pp.js | 4 +- ext/wasm/api/sqlite3-vfs-opfs.c-pp.js | 8 +- ext/wasm/api/sqlite3-worker1-promiser.c-pp.js | 10 +- ext/wasm/api/sqlite3-worker1.c-pp.js | 4 +- ext/wasm/c-pp.c | 246 +++++++++++++----- ext/wasm/demo-worker1-promiser.c-pp.js | 4 +- ext/wasm/mkwasmbuilds.c | 10 +- ext/wasm/tester1.c-pp.js | 6 +- manifest | 34 +-- manifest.uuid | 2 +- 13 files changed, 234 insertions(+), 114 deletions(-) diff --git a/ext/wasm/GNUmakefile b/ext/wasm/GNUmakefile index bcd45c58f8..dcf2ffec35 100644 --- a/ext/wasm/GNUmakefile +++ b/ext/wasm/GNUmakefile @@ -805,18 +805,18 @@ endef # # The various -D... values used by *.c-pp.js include: # -# -Dtarget=es6-module: for all ESM module builds +# -Dtarget:es6-module: for all ESM module builds # -# -Dtarget=node: for node.js builds +# -Dtarget:node: for node.js builds # -# -Dtarget=es6-module -Dtarget=es6-bundler-friendly: intended for +# -Dtarget:es6-module -Dtarget:es6-bundler-friendly: intended for # "bundler-friendly" ESM module build. These have some restrictions # on how URL() objects are constructed in some contexts: URLs which # refer to files which are part of this project must be referenced # as string literals so that bundlers' static-analysis tools can # find those files and include them in their bundles. # -# -Dtarget=es6-module -Dtarget=node: is intended for use by node.js +# -Dtarget:es6-module -Dtarget:node: is intended for use by node.js # for node.js, as opposed to by node.js on behalf of a # browser. Mixing -sENVIRONMENT=web and -sENVIRONMENT=node leads to # ambiguity and confusion on node's part, as it's unable to diff --git a/ext/wasm/api/extern-post-js.c-pp.js b/ext/wasm/api/extern-post-js.c-pp.js index db6592d4f2..0bb511d639 100644 --- a/ext/wasm/api/extern-post-js.c-pp.js +++ b/ext/wasm/api/extern-post-js.c-pp.js @@ -12,7 +12,7 @@ At the time this is run, the global-scope sqlite3InitModule function will have just been defined. */ -//#if target=es6-module +//#if target:es6-module const toExportForESM = //#endif (function(){ @@ -110,7 +110,7 @@ const toExportForESM = sIMS.scriptDir = src.join('/') + '/'; } sIMS.debugModule('extern-post-js.c-pp.js sqlite3InitModuleState =',sIMS); -//#ifnot target=es6-module +//#ifnot target:es6-module // Emscripten does not inject these module-loader bits in ES6 module // builds and including them here breaks JS bundlers, so elide them // from ESM builds. @@ -126,10 +126,10 @@ const toExportForESM = } /* AMD modules get injected in a way we cannot override, so we can't handle those here. */ -//#endif // !target=es6-module +//#endif // !target:es6-module return sIM; })(); -//#if target=es6-module +//#if target:es6-module sqlite3InitModule = toExportForESM; export default sqlite3InitModule; //#endif diff --git a/ext/wasm/api/pre-js.c-pp.js b/ext/wasm/api/pre-js.c-pp.js index 20d8456f3c..9cebda4c08 100644 --- a/ext/wasm/api/pre-js.c-pp.js +++ b/ext/wasm/api/pre-js.c-pp.js @@ -47,7 +47,7 @@ approach. */ Module['locateFile'] = function(path, prefix) { -//#if target=es6-module +//#if target:es6-module return new URL(path, import.meta.url).href; //#else 'use strict'; @@ -69,7 +69,7 @@ "result =", theFile ); return theFile; -//#endif target=es6-module +//#endif target:es6-module }.bind(sIMS); //#if Module.instantiateWasm diff --git a/ext/wasm/api/sqlite3-vfs-opfs-sahpool.c-pp.js b/ext/wasm/api/sqlite3-vfs-opfs-sahpool.c-pp.js index f489b36e21..5a59de9c9a 100644 --- a/ext/wasm/api/sqlite3-vfs-opfs-sahpool.c-pp.js +++ b/ext/wasm/api/sqlite3-vfs-opfs-sahpool.c-pp.js @@ -1,4 +1,4 @@ -//#ifnot target=node +//#ifnot target:node /* 2023-07-14 @@ -1460,4 +1460,4 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ The OPFS SAH Pool VFS parts are elided from builds targeting node.js. */ -//#endif target=node +//#endif target:node diff --git a/ext/wasm/api/sqlite3-vfs-opfs.c-pp.js b/ext/wasm/api/sqlite3-vfs-opfs.c-pp.js index 2b83a52e3a..a57efb4ef2 100644 --- a/ext/wasm/api/sqlite3-vfs-opfs.c-pp.js +++ b/ext/wasm/api/sqlite3-vfs-opfs.c-pp.js @@ -1,4 +1,4 @@ -//#ifnot target=node +//#ifnot target:node /* 2022-09-18 @@ -209,9 +209,9 @@ const installOpfsVfs = function callee(options){ return promiseResolve_(sqlite3); }; const W = -//#if target=es6-bundler-friendly +//#if target:es6-bundler-friendly new Worker(new URL("sqlite3-opfs-async-proxy.js", import.meta.url)); -//#elif target=es6-module +//#elif target:es6-module new Worker(new URL(options.proxyUri, import.meta.url)); //#else new Worker(options.proxyUri); @@ -1457,4 +1457,4 @@ globalThis.sqlite3ApiBootstrap.initializersAsync.push(async (sqlite3)=>{ }/*sqlite3ApiBootstrap.initializers.push()*/); //#else /* The OPFS VFS parts are elided from builds targeting node.js. */ -//#endif target=node +//#endif target:node diff --git a/ext/wasm/api/sqlite3-worker1-promiser.c-pp.js b/ext/wasm/api/sqlite3-worker1-promiser.c-pp.js index 29e64e94cf..db10ca0f7d 100644 --- a/ext/wasm/api/sqlite3-worker1-promiser.c-pp.js +++ b/ext/wasm/api/sqlite3-worker1-promiser.c-pp.js @@ -252,11 +252,11 @@ globalThis.sqlite3Worker1Promiser = function callee(config = callee.defaultConfi globalThis.sqlite3Worker1Promiser.defaultConfig = { worker: function(){ -//#if target=es6-bundler-friendly +//#if target:es6-bundler-friendly return new Worker(new URL("sqlite3-worker1-bundler-friendly.mjs", import.meta.url),{ type: 'module' }); -//#elif target=es6-module +//#elif target:es6-module return new Worker(new URL("sqlite3-worker1.js", import.meta.url)); //#else let theJs = "sqlite3-worker1.js"; @@ -275,7 +275,7 @@ globalThis.sqlite3Worker1Promiser.defaultConfig = { return new Worker(theJs + globalThis.location.search); //#endif } -//#ifnot target=es6-module +//#ifnot target:es6-module .bind({ currentScript: globalThis?.document?.currentScript }) @@ -334,7 +334,7 @@ globalThis.sqlite3Worker1Promiser.v2 = function callee(config = callee.defaultCo globalThis.sqlite3Worker1Promiser.v2.defaultConfig = globalThis.sqlite3Worker1Promiser.defaultConfig; -//#if target=es6-module +//#if target:es6-module /** When built as a module, we export sqlite3Worker1Promiser.v2() instead of sqlite3Worker1Promise() because (A) its interface is more @@ -343,7 +343,7 @@ globalThis.sqlite3Worker1Promiser.v2.defaultConfig = incompatibility. */ export default sqlite3Worker1Promiser.v2; -//#endif /* target=es6-module */ +//#endif /* target:es6-module */ //#else /* Built with the omit-oo1 flag. */ //#endif ifnot omit-oo1 diff --git a/ext/wasm/api/sqlite3-worker1.c-pp.js b/ext/wasm/api/sqlite3-worker1.c-pp.js index 243128fe1d..32bb370e39 100644 --- a/ext/wasm/api/sqlite3-worker1.c-pp.js +++ b/ext/wasm/api/sqlite3-worker1.c-pp.js @@ -32,9 +32,9 @@ - `sqlite3.dir`, if set, treats the given directory name as the directory from which `sqlite3.js` will be loaded. */ -//#if target=es6-bundler-friendly +//#if target:es6-bundler-friendly import {default as sqlite3InitModule} from './sqlite3-bundler-friendly.mjs'; -//#elif target=es6-module +//#elif target:es6-module return new Worker(new URL("sqlite3.js", import.meta.url)); //#else "use strict"; diff --git a/ext/wasm/c-pp.c b/ext/wasm/c-pp.c index dd6ebe211f..03db57b5da 100644 --- a/ext/wasm/c-pp.c +++ b/ext/wasm/c-pp.c @@ -16,13 +16,24 @@ ** minimal preprocessor with only the most basic functionality of a C ** preprocessor, namely: ** -** - Limited `#if`, where its one argument is a macro name which -** resolves to true if it's defined, false if it's not. Likewise, -** `#ifnot` is the inverse. Includes `#else` and `#elif` and -** `#elifnot`. Such chains are terminated with `#endif`. +** - Limited `#if`, where its one argument is a macro name or a +** name=value pair. If just the name is used, it's considered true +** if it has a non-empty value which is not '0', else it's false. If +** name=value is used then it resolves to true if the value matches, +** noting that value is treated like a glob. Likewise, `#ifnot` is +** the inverse. Includes `#else` and `#elif` and `#elifnot`. Such +** chains are terminated with `#endif`. More simply (and more +** recently) `#if` and `#elif` support two modifer words: `not` and +** `defined`, so can be used like: `#if not defined x` or +** `#if defined y`. ** -** - `#define` accepts one or more arguments, the names of -** macros. Each one is implicitly true. +** - `#assert` compares its arguments like `#if` but throws a fatal +** error if it's condition is falsy. Unlike `#if`, it does not +** open a new block. +** +** - `#define` accepts one or more arguments, the names or name=value +** list of macros. Each one with no explicit value defaults to a +** value of 1.. ** ** - `#undef` undefine one or more macros. ** @@ -39,7 +50,9 @@ ** - `#savepoint` takes one argument: begin, commit, rollback. Each ** corresponds to the similarly-named SQLite savepoint feature. ** (What we're calling "commit" is called "release" in savepoint -** terminology.) +** terminology.) Savepoints apply ONLY to the db-side data (namely +** #define and friends), not to content blocks. (Might that not +** be interesting, though?) ** ** - `#stderr` outputs its file name, line number, and the remainder ** of that line to stderr. @@ -48,6 +61,10 @@ ** space after the `//` part because `//` is (despite appearances) ** parsed like a keyword. ** +** - `#@policy@ NAME` sets the policy for handling `@tokens@` in +** the content parts of the input (as opposed to the keyword +** lines like this one). @ +** ** The "#" above is symbolic. The keyword delimiter is configurable ** and defaults to "##". Define CMPP_DEFAULT_DELIM to a string when ** compiling to define the default at build-time. @@ -197,12 +214,12 @@ static void db_free(void *m); ** any duplicates. Fails fatally on error. */ static void db_define_add(const char * zKey); + /* ** Returns true if the given key is already in the `#define` list, ** else false. Fails fatally on db error. */ -//static -int db_define_has(const char * zName); +static int db_define_has(const char * zName); /* ** Returns true if the given key is already in the `#define` list, and @@ -308,9 +325,12 @@ typedef struct FileWrapper FileWrapper; #define FileWrapper_empty_m {0,0,0,0} static const FileWrapper FileWrapper_empty = FileWrapper_empty_m; -/* Proxy for FILE_close(). */ +/* +** Proxy for FILE_close() and frees all memory owned by p. A no-op if +** p is already closed. +*/ static void FileWrapper_close(FileWrapper * p); -/* Proxy for FILE_open(). */ +/* Proxy for FILE_open(). Closes p first if it's currently opened. */ static void FileWrapper_open(FileWrapper * p, const char * zName, const char *zMode); /* Proxy for FILE_slurp(). */ static void FileWrapper_slurp(FileWrapper * p); @@ -446,6 +466,8 @@ TS_Error typedef enum CmppParseState CmppParseState; enum CmppTokenType { TT_Invalid = 0, +TT_Assert, +TT_AtPolicy, TT_Comment, TT_Define, TT_Elif, @@ -480,7 +502,8 @@ static const CmppToken CmppToken_empty = CmppToken_empty_m; /* ** CmppLevel represents one "level" of tokenization, starting at the ** top of the main input, incrementing once for each level of `#if`, -** and decrementing for each `#endif`. +** and decrementing for each `#endif`. Similarly, `#include` +** pushes a level. */ typedef struct CmppLevel CmppLevel; struct CmppLevel { @@ -794,20 +817,23 @@ void CmppLevel_push(CmppTokenizer * const t){ g.delim.z, CmppLevel_Max); } pPrev = &CT_level(t); - g_debug(3,("push from tokenizer level=%u flags=%04x\n", t->level.ndx, pPrev->flags)); + g_debug(3,("push from tokenizer level=%u flags=%04x\n", + t->level.ndx, pPrev->flags)); p = &t->level.stack[++t->level.ndx]; *p = CmppLevel_empty; p->token = t->token; p->flags = (CmppLevel_F_INHERIT_MASK & pPrev->flags); if(CLvl_skip(pPrev)) p->flags |= CmppLevel_F_ELIDE; - g_debug(3,("push to tokenizer level=%u flags=%04x\n", t->level.ndx, p->flags)); + g_debug(3,("push to tokenizer level=%u flags=%04x\n", + t->level.ndx, p->flags)); } void CmppLevel_pop(CmppTokenizer * const t){ if(!t->level.ndx){ fatal("Internal error: CmppLevel_pop() at the top of the stack"); } - g_debug(3,("pop from tokenizer level=%u, flags=%04x skipLevel?=%d\n", t->level.ndx, + g_debug(3,("pop from tokenizer level=%u, flags=%04x skipLevel?=%d\n", + t->level.ndx, t->level.stack[t->level.ndx].flags, CT_skipLevel(t))); g_debug(3,("CT_skipLevel() ?= %d\n",CT_skipLevel(t))); g_debug(3,("CT_skip() ?= %d\n",CT_skip(t))); @@ -825,6 +851,7 @@ CmppLevel * CmppLevel_get(CmppTokenizer * const t){ void db_affirm_rc(int rc, const char * zMsg){ if(rc){ + assert( g.db ); fatal("Db error #%d %s: %s", rc, zMsg, sqlite3_errmsg(g.db)); } @@ -836,8 +863,12 @@ void db_finalize(sqlite3_stmt *pStmt){ int db_step(sqlite3_stmt *pStmt){ int const rc = sqlite3_step(pStmt); - if(SQLITE_ROW!=rc && SQLITE_DONE!=rc){ - db_affirm_rc(rc, "from db_step()"); + switch( rc ){ + case SQLITE_ROW: + case SQLITE_DONE: + break; + default: + db_affirm_rc(rc, "from db_step()"); } return rc; } @@ -1522,7 +1553,8 @@ static int cmpp_next_keyword_line(CmppTokenizer * const t){ return isDelim; } -static void cmpp_kwd__err_prefix(CmppKeyword const * pKw, CmppTokenizer *t, +static void cmpp_kwd__err_prefix(CmppKeyword const * pKw, + CmppTokenizer const *t, char const *zPrefix){ g_stderr("%s%s%s @ %s line %u: ", zPrefix ? zPrefix : "", @@ -1531,9 +1563,9 @@ static void cmpp_kwd__err_prefix(CmppKeyword const * pKw, CmppTokenizer *t, } /* Internal error reporting helper for cmpp_keyword_f() impls. */ -static CMPP_NORETURN void cmpp_kwd__misuse(CmppKeyword const * pKw, - CmppTokenizer *t, - char const *zFmt, ...){ +static CMPP_NORETURN void cmpp_kwd__err(CmppKeyword const * pKw, + CmppTokenizer const *t, + char const *zFmt, ...){ va_list va; cmpp_kwd__err_prefix(pKw, t, "Fatal error"); va_start(va, zFmt); @@ -1563,7 +1595,7 @@ static void cmpp_kwd_error(CmppKeyword const * pKw, CmppTokenizer *t){ static void cmpp_kwd_define(CmppKeyword const * pKw, CmppTokenizer *t){ if(CT_skip(t)) return; if(t->args.argc<2){ - cmpp_kwd__misuse(pKw, t, "Expecting one or more arguments"); + cmpp_kwd__err(pKw, t, "Expecting one or more arguments"); }else{ int i = 1; void (*func)(const char *) = TT_Define==pKw->ttype @@ -1578,58 +1610,128 @@ static void cmpp_kwd_define(CmppKeyword const * pKw, CmppTokenizer *t){ static void cmpp_kwd_if(CmppKeyword const * pKw, CmppTokenizer *t){ int buul = 0; CmppParseState tmpState = TS_Start; - if(t->args.argc!=2){ - cmpp_kwd__misuse(pKw, t, "Expecting exactly 1 argument"); + /** + TT_If: accept args: + + - "not" = negates the operation + + - "defined" == is-defined op + */ + int bCheckDefined = 0; + int bNot = 0; + char const * zKey = 0; + char const *zEq = 0; + + assert( TT_If==pKw->ttype + || TT_IfNot==pKw->ttype + || TT_Elif==pKw->ttype + || TT_ElifNot==pKw->ttype + || TT_Assert==pKw->ttype); + if(t->args.argc<2){ + cmpp_kwd__err(pKw, t, "Expecting an argument"); + } + switch( pKw->ttype ){ + case TT_IfNot: + case TT_ElifNot: bNot = 1; + /* fall through */ + case TT_If: + case TT_Assert: + case TT_Elif: + for( int i = 1; i < t->args.argc; ++i ){ + char const * z = (char const *)t->args.argv[i]; + if( 0==strcmp(z, "not") ){ + bNot = !bNot; + }else if( 0==strcmp(z,"defined") ){ + if( bCheckDefined ){ + cmpp_kwd__err(pKw, t, + "Cannot use 'defined' more than once"); + } + bCheckDefined = 1; + }else if( !zKey ){ + zKey = (char const *)t->args.argv[i]; + }else{ + cmpp_kwd__err(pKw, t, "Unhandled argument: %s", z); + } + } + if( !zKey ){ + cmpp_kwd__err(pKw, t, "Missing key argument"); + } + break; + default: + if(t->args.argc!=2){ + cmpp_kwd__err(pKw, t, "Expecting exactly 1 argument"); + } + zKey = (char const *)t->args.argv[1]; } - /*g_debug(0,("%s %s level %u pstate=%d\n", pKw->zName, - (char const *)t->args.argv[1], - t->level.ndx, (int)CT_pstate(t)));*/ + /*g_debug(0,("%s %s level %u pstate=%d bNot=%d bCheckDefined=%d\n", + pKw->zName, zKey, t->level.ndx, (int)CT_pstate(t), + bNot, bCheckDefined));*/ switch(pKw->ttype){ case TT_Elif: case TT_ElifNot: switch(CT_pstate(t)){ case TS_If: break; case TS_IfPassed: CT_level(t).flags |= CmppLevel_F_ELIDE; return; - default: goto misuse; + default: + cmpp_kwd__err(pKw, t, "'%s' used out of context", + pKw->zName); } break; case TT_If: case TT_IfNot: CmppLevel_push(t); break; + case TT_Assert: + break; default: - cmpp_kwd__misuse(pKw, t, "Unexpected keyword token type"); + assert(!"cannot happen"); + cmpp_kwd__err(pKw, t, "Unexpected keyword token type"); break; } - char const * const zKey = (char const *)t->args.argv[1]; - char const * zEq = 0; unsigned nValPart = 0; char const * zValPart = cmpp_val_part(zKey, -1, '=', &nValPart, &zEq); + /*g_debug(0,("%s %s level %u pstate=%d bNot=%d bCheckDefined=%d " + "nValPart=%u zValPart=%s\n", + pKw->zName, zKey, t->level.ndx, (int)CT_pstate(t), + bNot, bCheckDefined, nValPart, zValPart));*/ if( zValPart ){ + if( bCheckDefined ){ + cmpp_kwd__err(pKw, t, "Value part is not legal with %s: %s", + pKw->zName, zKey); + } unsigned nVal = 0; char * zVal = 0; buul = db_define_get(zKey, (zEq-zKey), &zVal, &nVal); + //g_debug(0,("checking key[%.*s]=%.*s\n", (zEq-zKey), zKey, nVal, zVal)); if( nVal ){ /* FIXME? do this with a query */ - g_debug(1,("if get-define %.*s=%.*s zValPart=%s\n", + /*g_debug(0,("if get-define [%.*s]=[%.*s] zValPart=%s\n", (zEq-zKey), zKey, - nVal, zVal, zValPart)); + nVal, zVal, zValPart));*/ buul = 0==sqlite3_strglob(zValPart,zVal); + //g_debug(0,("buul=%d\n", buul)); } db_free(zVal); }else{ - buul = db_define_get_bool(zKey, -1); + if( bCheckDefined ){ + buul = db_define_has(zKey); + }else{ + buul = db_define_get_bool(zKey, -1); + } } - if(TT_IfNot==pKw->ttype || TT_ElifNot==pKw->ttype) buul = !buul; - if(buul){ + //if( bNot ) buul = !buul; + if( bNot ? !buul : buul ){ CT_pstate(t) = tmpState = TS_IfPassed; CT_skipLevel(t) = 0; }else{ + if( TT_Assert==pKw->ttype ){ + cmpp_kwd__err(pKw, t, "Assertion failed: %s", zKey); + } CT_pstate(t) = TS_If /* also for TT_IfNot, TT_Elif, TT_ElifNot */; CT_skipLevel(t) = 1; g_debug(3,("setting CT_skipLevel = 1 @ level %d\n", t->level.ndx)); } - if(TT_If==pKw->ttype || TT_IfNot==pKw->ttype){ + if( TT_If==pKw->ttype || TT_IfNot==pKw->ttype ){ unsigned const lvlIf = t->level.ndx; CmppToken const lvlToken = CT_level(t).token; while(cmpp_next_keyword_line(t)){ @@ -1647,29 +1749,25 @@ static void cmpp_kwd_if(CmppKeyword const * pKw, CmppTokenizer *t){ #endif } if(lvlIf <= t->level.ndx){ - cmpp_kwd__err_prefix(pKw, t, NULL); - fatal("Input ended inside an unterminated %sif " - "opened at [%s] line %u", - g.delim.z, t->zName, lvlToken.lineNo); + cmpp_kwd__err(pKw, t, + "Input ended inside an unterminated %sif " + "opened at [%s] line %u", + g.delim.z, t->zName, lvlToken.lineNo); } } - return; - misuse: - cmpp_kwd__misuse(pKw, t, "'%s' used out of context", - pKw->zName); } /* Impl. for #else. */ static void cmpp_kwd_else(CmppKeyword const * pKw, CmppTokenizer *t){ if(t->args.argc>1){ - cmpp_kwd__misuse(pKw, t, "Expecting no arguments"); + cmpp_kwd__err(pKw, t, "Expecting no arguments"); } switch(CT_pstate(t)){ case TS_IfPassed: CT_skipLevel(t) = 1; break; case TS_If: CT_skipLevel(t) = 0; break; default: - cmpp_kwd__misuse(pKw, t, "'%s' with no matching 'if'", - pKw->zName); + cmpp_kwd__err(pKw, t, "'%s' with no matching 'if'", + pKw->zName); } /*g_debug(0,("else flags=0x%02x skipLevel=%u\n", CT_level(t).flags, CT_level(t).skipLevel));*/ @@ -1690,8 +1788,8 @@ static void cmpp_kwd_endif(CmppKeyword const * pKw, CmppTokenizer *t){ case TS_IfPassed: break; default: - cmpp_kwd__misuse(pKw, t, "'%s' with no matching 'if'", - pKw->zName); + cmpp_kwd__err(pKw, t, "'%s' with no matching 'if'", + pKw->zName); } CmppLevel_pop(t); } @@ -1702,7 +1800,7 @@ static void cmpp_kwd_include(CmppKeyword const * pKw, CmppTokenizer *t){ char * zResolved; if(CT_skip(t)) return; else if(t->args.argc!=2){ - cmpp_kwd__misuse(pKw, t, "Expecting exactly 1 filename argument"); + cmpp_kwd__err(pKw, t, "Expecting exactly 1 filename argument"); } zFile = (const char *)t->args.argv[1]; if(db_including_has(zFile)){ @@ -1732,7 +1830,7 @@ static void cmpp_kwd_pragma(CmppKeyword const * pKw, CmppTokenizer *t){ const char * zArg; if(CT_skip(t)) return; else if(t->args.argc<2){ - cmpp_kwd__misuse(pKw, t, "Expecting an argument"); + cmpp_kwd__err(pKw, t, "Expecting an argument"); } zArg = (const char *)t->args.argv[1]; #define M(X) 0==strcmp(zArg,X) @@ -1746,7 +1844,15 @@ static void cmpp_kwd_pragma(CmppKeyword const * pKw, CmppTokenizer *t){ g_stderr("\t%.*s\n", n, z); } db_finalize(q); - }else if(M("@")){ + } + else if(M("chomp-F")){ + g.flags.chompF = 1; + }else if(M("no-chomp-F")){ + g.flags.chompF = 0; + } +#if 0 + /* now done by cmpp_kwd_at_policy() */ + else if(M("@")){ if(t->args.argc>2){ g.flags.atPolicy = AtPolicy_fromStr((char const *)t->args.argv[2], 1); @@ -1755,12 +1861,10 @@ static void cmpp_kwd_pragma(CmppKeyword const * pKw, CmppTokenizer *t){ } }else if(M("no-@")){ g.flags.atPolicy = AT_OFF; - }else if(M("chomp-F")){ - g.flags.chompF = 1; - }else if(M("no-chomp-F")){ - g.flags.chompF = 0; - }else{ - cmpp_kwd__misuse(pKw, t, "Unknown pragma: %s", zArg); + } +#endif + else{ + cmpp_kwd__err(pKw, t, "Unknown pragma: %s", zArg); } #undef M } @@ -1770,7 +1874,7 @@ static void cmpp_kwd_savepoint(CmppKeyword const * pKw, CmppTokenizer *t){ const char * zArg; if(CT_skip(t)) return; else if(t->args.argc!=2){ - cmpp_kwd__misuse(pKw, t, "Expecting one argument"); + cmpp_kwd__err(pKw, t, "Expecting one argument"); } zArg = (const char *)t->args.argv[1]; #define SP_NAME " cmpp /*" __FILE__ "*/;" @@ -1794,7 +1898,7 @@ static void cmpp_kwd_savepoint(CmppKeyword const * pKw, CmppTokenizer *t){ ), "Committing a savepoint" ); }else{ - cmpp_kwd__misuse(pKw, t, "Unknown savepoint option: %s", zArg); + cmpp_kwd__err(pKw, t, "Unknown savepoint option: %s", zArg); } #undef SP_NAME #undef M @@ -1816,6 +1920,17 @@ static void cmpp_kwd_stderr(CmppKeyword const * pKw, CmppTokenizer *t){ } } +/* Impl. for the @ policy. */ +static void cmpp_kwd_at_policy(CmppKeyword const * pKw, CmppTokenizer *t){ + if(CT_skip(t)) return; + else if(t->args.argc<2){ + g.flags.atPolicy = AT_DEFAULT; + }else{ + g.flags.atPolicy = AtPolicy_fromStr((char const*)t->args.argv[1], 1); + } +} + + #if 0 /* Impl. for dummy placeholder. */ static void cmpp_kwd_todo(CmppKeyword const * pKw, CmppTokenizer *t){ @@ -1827,6 +1942,8 @@ static void cmpp_kwd_todo(CmppKeyword const * pKw, CmppTokenizer *t){ CmppKeyword aKeywords[] = { /* Keep these sorted by zName */ {"//", 2, 0, TT_Comment, cmpp_kwd_noop}, + {"@policy@", 8, 1, TT_AtPolicy, cmpp_kwd_at_policy}, + {"assert", 3, 1, TT_Assert, cmpp_kwd_if}, {"define", 6, 1, TT_Define, cmpp_kwd_define}, {"elif", 4, 1, TT_Elif, cmpp_kwd_if}, {"elifnot", 7, 1, TT_ElifNot, cmpp_kwd_if}, @@ -1987,8 +2104,11 @@ static int arg_is_flag( char const *zFlag, char const *zArg, if( z && z>zArg ){ /* compare the part before the '=' */ if( 0==strncmp(zFlag, zArg, z-zArg) ){ - *zValIfEqX = z+1; - return 1; + if( !zFlag[z-zArg] ){ + *zValIfEqX = z+1; + return 1; + } + /* Else it was a prefix match. */ } } return 0; diff --git a/ext/wasm/demo-worker1-promiser.c-pp.js b/ext/wasm/demo-worker1-promiser.c-pp.js index 0b8557b826..bd12035d15 100644 --- a/ext/wasm/demo-worker1-promiser.c-pp.js +++ b/ext/wasm/demo-worker1-promiser.c-pp.js @@ -13,7 +13,7 @@ Demonstration of the sqlite3 Worker API #1 Promiser: a Promise-based proxy for for the sqlite3 Worker #1 API. */ -//#if target=es6-module +//#if target:es6-module import {default as promiserFactory} from "./jswasm/sqlite3-worker1-promiser.mjs"; //#else "use strict"; @@ -40,7 +40,7 @@ delete globalThis.sqlite3Worker1Promiser; }; const promiserConfig = { -//#ifnot target=es6-module +//#ifnot target:es6-module /** The v1 interfaces uses an onready function. The v2 interface optionally accepts one but does not require it. If provided, it is called _before_ diff --git a/ext/wasm/mkwasmbuilds.c b/ext/wasm/mkwasmbuilds.c index add4bb8f8d..39cebfdc1a 100644 --- a/ext/wasm/mkwasmbuilds.c +++ b/ext/wasm/mkwasmbuilds.c @@ -247,7 +247,7 @@ const BuildDefs oBuildDefs = { .zEmo = "🍬", .zBaseName = "sqlite3", .zDotWasm = 0, - .zCmppD = "-Dtarget=es6-module", + .zCmppD = "-Dtarget:es6-module", .zEmcc = 0, .zEmccExtra = 0, .zEnv = 0, @@ -261,7 +261,7 @@ const BuildDefs oBuildDefs = { .zEmo = "🍫", .zBaseName = "sqlite3-64bit", .zDotWasm = 0, - .zCmppD = "-Dtarget=es6-module", + .zCmppD = "-Dtarget:es6-module", .zEmcc = 0, .zEmccExtra = "-sMEMORY64=1 -sWASM_BIGINT=1", .zEnv = 0, @@ -339,7 +339,7 @@ const BuildDefs oBuildDefs = { .zEmo = "👛", .zBaseName = "sqlite3-bundler-friendly", .zDotWasm = "sqlite3", - .zCmppD = "$(c-pp.D.esm) -Dtarget=es6-bundler-friendly", + .zCmppD = "$(c-pp.D.esm) -Dtarget:es6-bundler-friendly", .zEmcc = 0, .zEmccExtra = 0, .zEnv = 0, @@ -372,7 +372,7 @@ const BuildDefs oBuildDefs = { .zEmo = "🍟", .zBaseName = "sqlite3-node", .zDotWasm = 0, - .zCmppD = "-Dtarget=node $(c-pp.D.bundler)", + .zCmppD = "-Dtarget:node $(c-pp.D.bundler)", .zEmcc = 0, .zEmccExtra = 0, .zEnv = "node" @@ -390,7 +390,7 @@ const BuildDefs oBuildDefs = { .zEmo = "🍔", .zBaseName = "sqlite3-node-64bit", .zDotWasm = 0, - .zCmppD = "-Dtarget=node $(c-pp.D.bundler)", + .zCmppD = "-Dtarget:node $(c-pp.D.bundler)", .zEmcc = 0, .zEmccExtra = 0, .zEnv = "node", diff --git a/ext/wasm/tester1.c-pp.js b/ext/wasm/tester1.c-pp.js index ce33b55260..39440f3b34 100644 --- a/ext/wasm/tester1.c-pp.js +++ b/ext/wasm/tester1.c-pp.js @@ -41,9 +41,9 @@ ES6 worker module build: - ./c-pp -f tester1.c-pp.js -o tester1-esm.mjs -Dtarget=es6-module + ./c-pp -f tester1.c-pp.js -o tester1-esm.mjs -Dtarget:es6-module */ -//#if target=es6-module +//#if target:es6-module import {default as sqlite3InitModule} from //#if 64bit './jswasm/sqlite3-64bit.mjs' @@ -3805,7 +3805,7 @@ globalThis.sqlite3InitModule = sqlite3InitModule; error: ()=>{} } } -//#ifnot target=es6-module +//#ifnot target:es6-module if(!globalThis.sqlite3InitModule && !isUIThread()){ /* Vanilla worker, as opposed to an ES6 module worker */ /* diff --git a/manifest b/manifest index 60d2abb520..9b75fdfc72 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Rework\sthe\sbounds\scalculations\son\sgenerate_series()\sin\san\sattempt\sto\navoid\ssigned\sinteger\soverflow\swhen\sthe\sbounds\sare\sridiculous\svalues. -D 2025-09-27T15:03:11.176 +C Improve\s#if\ssupport\sin,\sand\sadd\s#assert\sto,\sc-pp.\sRename\starget=...\spreprocessor\ssymbols\sto\starget:...\sbecause\schanges\sin\sthe\ssemantics\sfor\ssymbols\swhich\shave\san\s'='\smakes\ssome\sof\sthose\s#if\sblocks\smutually\sexclusive\s(which\swe\swon't\swant\sin\srare\scases\sinvolving\sthe\sbundler-friendly\sbuilds). +D 2025-09-28T00:53:00.300 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea @@ -578,7 +578,7 @@ F ext/session/sqlite3session.c b3de195ce668cace9b324599bf6255a70290cbfb5451e826e F ext/session/sqlite3session.h 7404723606074fcb2afdc6b72c206072cdb2b7d8ba097ca1559174a80bc26f7a F ext/session/test_session.c 8766b5973a6323934cb51248f621c3dc87ad2a98f023c3cc280d79e7d78d36fb F ext/wasm/EXPORTED_FUNCTIONS.fiddle.in 27450c8b8c70875a260aca55435ec927068b34cef801a96205adb81bdcefc65c -F ext/wasm/GNUmakefile a0b4f179bbaa295171bb00eb8ae20a28c634e47bedfe9339ac3ed0e351b7931a +F ext/wasm/GNUmakefile e06543750e8ed35baa8bba31ad3e357bb13f2dc8fe75cb491fe2d6f2167110a2 F ext/wasm/README-dist.txt f01081a850ce38a56706af6b481e3a7878e24e42b314cfcd4b129f0f8427066a F ext/wasm/README.md 66ace67ae98a45e4116f2ca5425b716887bcee4d64febee804ff6398e1ae9ec7 F ext/wasm/SQLTester/GNUmakefile e0794f676d55819951bbfae45cc5e8d7818dc460492dc317ce7f0d2eca15caff @@ -591,11 +591,11 @@ F ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-extras cb4fa8842c875b6ee99381523792975 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 f4c0d67caaee21a77b8938c30b5f79667bfc9d0c95d01b51df77ea35ee773884 -F ext/wasm/api/extern-post-js.c-pp.js 8ed3cefbc2b73e2c16afae7bf64917361fdd26871f0d427d422cf48b7b2b40c5 +F ext/wasm/api/extern-post-js.c-pp.js eaa41ddccf70c3bb3b953e4edd1c0cb82e695166d86ae8dc36b59b09631e2741 F ext/wasm/api/extern-pre-js.js cc61c09c7a24a07dbecb4c352453c3985170cec12b4e7e7e7a4d11d43c5c8f41 F ext/wasm/api/post-js-footer.js 5bd7170b5e8ce7b62102702bbcf47ef7b3b49cd56ed40c043fd990aa715b74ee F ext/wasm/api/post-js-header.js 79d078aec33d93b640a19c574b504d88bb2446432f38e2fbb3bb8e36da436e70 -F ext/wasm/api/pre-js.c-pp.js a03310c02d3bcf1414ea4a6a5e8070155184d56d01bf0f9e17d26162a4bdb1d0 +F ext/wasm/api/pre-js.c-pp.js c53ece7660afcc8db7f697428dccac6a6b48ef20c43b430561e7e7f843e9a0b9 F ext/wasm/api/sqlite3-api-cleanup.js a3d6b9e449aefbb8bba283c2ba9477e2333a0eeb94a7a26b5bf952736f65a6dd F ext/wasm/api/sqlite3-api-glue.c-pp.js 12f5b36775fab1e7bf5385689fded2b2a9f77360562515e9849acb5e66602e2d F ext/wasm/api/sqlite3-api-oo1.c-pp.js db4c8ebb03bac60db32ce03f8c615b00f4e4ad53e7d5de5e63d2780cba052caa @@ -604,13 +604,13 @@ F ext/wasm/api/sqlite3-api-worker1.c-pp.js 760191cd13416e6f5adfd9fcc8a97fed5645c F ext/wasm/api/sqlite3-license-version-header.js 0c807a421f0187e778dc1078f10d2994b915123c1223fe752b60afdcd1263f89 F ext/wasm/api/sqlite3-opfs-async-proxy.js 9654b565b346dc609b75d15337f20acfa7af7d9d558da1afeb9b6d8eaa404966 F ext/wasm/api/sqlite3-vfs-helper.c-pp.js 3f828cc66758acb40e9c5b4dcfd87fd478a14c8fb7f0630264e6c7fa0e57515d -F ext/wasm/api/sqlite3-vfs-opfs-sahpool.c-pp.js e2c0bd6917b697137035d775ed3300e603642ac845568402fcf712641fbcc5d2 -F ext/wasm/api/sqlite3-vfs-opfs.c-pp.js f8e762aeb568e0fd050ab991c5f3420dca9c14630386e4e18d42c0624b8ff7cd +F ext/wasm/api/sqlite3-vfs-opfs-sahpool.c-pp.js f78ba02f7855355513f271d0955a01a7f86a2a8884c278053f578662b2a3b268 +F ext/wasm/api/sqlite3-vfs-opfs.c-pp.js 17f172182ff2fd4ad5dc2c2d79aef339b307cb2fa345b0521864baf20262fe6e F ext/wasm/api/sqlite3-vtab-helper.c-pp.js 9097074724172e31e56ce20ccd7482259cf72a76124213cbc9469d757676da86 F ext/wasm/api/sqlite3-wasm.c ff2dc011e17b06186b8b35e408626d7ace69a362b92c197a34d78bef25c7105a -F ext/wasm/api/sqlite3-worker1-promiser.c-pp.js 8fb6adfbae6270344f43f2652e63780df3f86521755bde8f92cf6b809ba7891d -F ext/wasm/api/sqlite3-worker1.c-pp.js 69483df1df2d0988e708390f7b1feda769c16e9e9efd4683557f8e7197099cc0 -F ext/wasm/c-pp.c c0c48f2d302d13d1c9f340aa8ace68b36de2cf5a9b4f6e9ce1c3b20e3554c46f +F ext/wasm/api/sqlite3-worker1-promiser.c-pp.js a72cb1f2a4170e79a595a8d420fac02e4eec8e2a65aefa9eed081b30845c44c7 +F ext/wasm/api/sqlite3-worker1.c-pp.js fa330c5c9e14277ce85e65c0fdb5d28ee983fcf664d29e23451ac184c1771ec9 +F ext/wasm/c-pp.c a45acfd57204af7782fc0eac455d2ca2068133e81aa4c55d58e18070ffca1ea0 F ext/wasm/common/SqliteTestUtil.js 7adaeffef757d8708418dc9190f72df22367b531831775804b31598b44f6aa51 F ext/wasm/common/emscripten.css 11bd104b6c0d597c67d40cc8ecc0a60dae2b965151e3b6a37fa5708bac3acd15 F ext/wasm/common/testing.css e97549bab24126c24e0daabfe2de9bb478fb0a69fdb2ddd0a73a992c091aad6f @@ -622,7 +622,7 @@ F ext/wasm/demo-123.js c7b3cca50c55841c381a9ca4f9396e5bbdc6114273d0b10a43e378e32 F ext/wasm/demo-jsstorage.html 409c4be4af5f207fb2877160724b91b33ea36a3cd8c204e8da1acb828ffe588e F ext/wasm/demo-jsstorage.js 42131ddfa18e817d0e39ac63745e9ea31553980a5ebd2222e04d4fac60c19837 F ext/wasm/demo-worker1-promiser.c-pp.html 635cf90685805e21772a5f7a35d1ace80f98a9ef7c42ff04d7a125ddca7e5db8 -F ext/wasm/demo-worker1-promiser.c-pp.js af168699d3cab1c27ad2364ebe06cd49db300bdbf404e23b00d5742ed52816ba +F ext/wasm/demo-worker1-promiser.c-pp.js 165ca6c6b41876afc6cbcd8a1610410694f26fa27a47656d8edbb456170c22c3 F ext/wasm/demo-worker1.html 2c178c1890a2beb5a5fecb1453e796d067a4b8d3d2a04d65ca2eb1ab2c68ef5d F ext/wasm/demo-worker1.js 08720227e98fa5b44761cf6e219269cee3e9dd0421d8d91459535da776950314 F ext/wasm/example_extra_init.c 2347cd69d19d839ef4e5e77b7855103a7fe3ef2af86f2e8c95839afd8b05862f @@ -634,7 +634,7 @@ F ext/wasm/index.html 1b06cef70db4b2d5c0af1f9e6e32b27c1ca298cde97365a887926d501f F ext/wasm/jaccwabyt/jaccwabyt.js bbac67bc7a79dca34afe6215fd16b27768d84e22273507206f888c117e2ede7d F ext/wasm/jaccwabyt/jaccwabyt.md 167fc0b624c9bc2c477846e336de9403842d81b1a24fc4d3b24317cb9eba734f F ext/wasm/mkdist.sh 29f8a37a7aba41fa5df8e89b1fab02b83b35c43473c5cf808584872e022514b8 x -F ext/wasm/mkwasmbuilds.c b29e041d7ac096897ce1e75abff2e8b2608a17b05a02fba7c06ad58da49fa577 +F ext/wasm/mkwasmbuilds.c 9d79591ec644f14c6fb06a9cb52f723dbce4d15583058af8bcc87609ee6020d1 F ext/wasm/module-symbols.html e54f42112e0aac2a31f850ab33e7f2630a2ea4f63496f484a12469a2501e07e2 F ext/wasm/scratchpad-wasmfs.html a3d7388f3c4b263676b58b526846e9d02dfcb4014ff29d3a5040935286af5b96 F ext/wasm/scratchpad-wasmfs.mjs 66034b9256b218de59248aad796760a1584c1dd842231505895eff00dbd57c63 @@ -650,7 +650,7 @@ F ext/wasm/test-opfs-vfs.html 1f2d672f3f3fce810dfd48a8d56914aba22e45c6834e262555 F ext/wasm/test-opfs-vfs.js 1618670e466f424aa289859fe0ec8ded223e42e9e69b5c851f809baaaca1a00c F ext/wasm/tester1-worker.c-pp.html b240b59cd313427434190d5795f57986b9add1a08df53921311fc0b8221b672a F ext/wasm/tester1.c-pp.html 93fbedb6b15eaad9b03df0524c702a81896e358785655ae2c751e30ef8202e54 -F ext/wasm/tester1.c-pp.js 2b2aea6d9938fcfad0e3fd8ae094bced45212b807812b60a0dbe970f7f143f82 +F ext/wasm/tester1.c-pp.js 79bd0476f5c27bf064e3ee996f4c68cf2f6e013f51e455480c66c5ce9812069a 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 @@ -2169,8 +2169,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 1ad0169b022b280bcaaf94a7fa231591be96b514230ab5c98fbf15cd7df842dd F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P b44650f907e9cb4ec908bb7525488e309946fac9d84cdac4cdde730527a440a9 -R d5846da0ab3c8c6a5964b44c05b2978e -U drh -Z fa03ae8701fe595d404c20bdd78a00d1 +P 3d9148c7d7379a34a0c2a33a1eb2562234868bc0b14c3d16990b33e52fd4ebc5 +R c3b2080000fd0185e7e9f2ef37cc7ba6 +U stephan +Z 4c209bd96d28f6fa8a3b32a05c00f5b7 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 0367d45468..11bfaa956c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -3d9148c7d7379a34a0c2a33a1eb2562234868bc0b14c3d16990b33e52fd4ebc5 +54287487793d48f6dde919446ab7476aea0cc0aba3835c80f060a7b84221881a -- 2.47.3