From f8cd3d2b5c71b305754407e20ef282a0aeb2e0eb Mon Sep 17 00:00:00 2001 From: stephan Date: Wed, 18 May 2022 17:14:24 +0000 Subject: [PATCH 01/19] Initial version of an sqlfiddle-style application using a WASM build of the sqlite3 shell. FossilOrigin-Name: af9c21c9e0caf05adac7a9fcde39a9164c89f1c78b767b6fdd74a1405a3d373f --- Makefile.in | 21 ++++ ext/fiddle/Makefile | 5 + ext/fiddle/fiddle.in.html | 208 ++++++++++++++++++++++++++++++++++++++ ext/fiddle/index.md | 71 +++++++++++++ manifest | 22 ++-- manifest.uuid | 2 +- src/shell.c.in | 130 ++++++++++++++++++++++-- 7 files changed, 443 insertions(+), 16 deletions(-) create mode 100644 ext/fiddle/Makefile create mode 100644 ext/fiddle/fiddle.in.html create mode 100644 ext/fiddle/index.md diff --git a/Makefile.in b/Makefile.in index e5d30d030b..92b2525d58 100644 --- a/Makefile.in +++ b/Makefile.in @@ -1512,3 +1512,24 @@ sqlite3.def: $(REAL_LIBOBJ) sqlite3.dll: $(REAL_LIBOBJ) sqlite3.def $(TCC) -shared -o $@ sqlite3.def \ -Wl,"--strip-all" $(REAL_LIBOBJ) + + +# +# fiddle section +# +fiddle_dir = ext/fiddle +fiddle_tmpl = $(fiddle_dir)/fiddle.in.html +fiddle_html = $(fiddle_dir)/fiddle.html +fiddle_generated = $(fiddle_html) \ + $(fiddle_dir)/fiddle.js \ + $(fiddle_dir)/fiddle.wasm +clean-fiddle: + rm -f $(fiddle_generated) +clean: clean-fiddle +emcc_flags = -sEXPORTED_RUNTIME_METHODS=ccall,cwrap \ + -sEXPORTED_FUNCTIONS=_fiddle_exec \ + --shell-file $(fiddle_tmpl) +$(fiddle_html): Makefile sqlite3.c shell.c $(fiddle_tmpl) + emcc -o $@ $(emcc_flags) sqlite3.c shell.c + +fiddle: $(fiddle_html) diff --git a/ext/fiddle/Makefile b/ext/fiddle/Makefile new file mode 100644 index 0000000000..a3bc352aec --- /dev/null +++ b/ext/fiddle/Makefile @@ -0,0 +1,5 @@ +default: + make -C ../.. fiddle + +clean: + make -C ../../ clean-fiddle diff --git a/ext/fiddle/fiddle.in.html b/ext/fiddle/fiddle.in.html new file mode 100644 index 0000000000..ddd7d6984c --- /dev/null +++ b/ext/fiddle/fiddle.in.html @@ -0,0 +1,208 @@ + + + + + + sqlite3 fiddle + + + +
sqlite3 fiddle
+
emscripten
+
Downloading...
+
+ +
+
+
+ +
+ + +
+
+
+ +
+ +
+
+
+
+ Options +
+ + +
+
+
+ + {{{ SCRIPT }}} + + diff --git a/ext/fiddle/index.md b/ext/fiddle/index.md new file mode 100644 index 0000000000..9f5ab41b9a --- /dev/null +++ b/ext/fiddle/index.md @@ -0,0 +1,71 @@ +This directory houses a "fiddle"-style application which embeds a +[Web Assembly (WASM)](https://en.wikipedia.org/wiki/WebAssembly) +build of the sqlite3 shell app into an HTML page, effectively running +the shell in a client-side browser. + +It requires [emscripten][] and that the build environment be set up for +emscripten. A mini-HOWTO for setting that up follows... + +First, install the Emscripten SDK, as documented +[here](https://emscripten.org/docs/getting_started/downloads.html) and summarized +below for Linux environments: + +``` +# Clone the emscripten repository: +$ git clone https://github.com/emscripten-core/emsdk.git +$ cd emsdk + +# Download and install the latest SDK tools: +$ ./emsdk install latest + +# Make the "latest" SDK "active" for the current user: +$ ./emsdk activate latest +``` + +Those parts only need to be run once. The following needs to be run for each +shell instance which needs the `emcc` compiler: + +``` +# Activate PATH and other environment variables in the current terminal: +$ source ./emsdk_env.sh + +$ which emcc +/path/to/emsdk/upstream/emscripten/emcc +``` + +That `env` script needs to be sourced for building this application from the +top of the sqlite3 build tree: + +``` +$ make fiddle +``` + +Or: + +``` +$ cd ext/fiddle +$ make +``` + +That will generate the fiddle application under +[ext/fiddle](/dir/ext/fiddle), as `fiddle.html`. That application +cannot, due to XMLHttpRequest security limitations, run if the HTML +file is opened directly in the browser (i.e. if it is opened using a +`file://` URL), so it needs to be served via an HTTP server. For +example, using [althttpd][]: + +``` +$ cd ext/fiddle +$ althttpd -debug 1 -jail 0 -port 9090 -root . +``` + +Then browse to `http://localhost:9090/fiddle.html`. + +Note that when serving this app via [althttpd][], it must be a version +from 2022-05-17 or newer so that it recognizes the `.wasm` file +extension and responds with the mimetype `application/wasm`, as the +wasm loader is pedantic about that detail. + + +[emscripten]: https://emscripten.org +[althttpd]: https://sqlite.org/althttpd diff --git a/manifest b/manifest index 7f1d327e7e..2cc14ec5e2 100644 --- a/manifest +++ b/manifest @@ -1,9 +1,9 @@ -C Fix\sharmless\scompiler\swarnings\sin\sthe\snew\sunixFullPathname\simplementation. -D 2022-05-17T15:11:57.632 +C Initial\sversion\sof\san\ssqlfiddle-style\sapplication\susing\sa\sWASM\sbuild\sof\sthe\ssqlite3\sshell. +D 2022-05-18T17:14:24.622 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 -F Makefile.in b210ad2733317f1a4353085dfb9d385ceec30b0e6a61d20a5accabecac6b1949 +F Makefile.in ff32504cde350caaf4d52abfdca5dd1fa88b21e53071a0f9cc3539b6789c3606 F Makefile.linux-gcc f609543700659711fbd230eced1f01353117621dccae7b9fb70daa64236c5241 F Makefile.msc b28a8a7a977e7312f6859f560348e1eb110c21bd6cf9fab0d16537c0a514eef3 F README.md 8b8df9ca852aeac4864eb1e400002633ee6db84065bd01b78c33817f97d31f5e @@ -55,6 +55,9 @@ F ext/expert/expert1.test 3c642a4e7bbb14f21ddab595436fb465a4733f47a0fe5b2855e1d5 F ext/expert/sqlite3expert.c 6ca30d73b9ed75bd56d6e0d7f2c962d2affaa72c505458619d0ff5d9cdfac204 F ext/expert/sqlite3expert.h ca81efc2679a92373a13a3e76a6138d0310e32be53d6c3bfaedabd158ea8969b F ext/expert/test_expert.c d56c194b769bdc90cf829a14c9ecbc1edca9c850b837a4d0b13be14095c32a72 +F ext/fiddle/Makefile ea647919e6ac4b50edde1490f60ee87e8ccd75141e4aa650718c6f28eb323bbc +F ext/fiddle/fiddle.in.html 85db5e736f82fd2cae1c4f61b5af62239cc5db363b9eb6f4e383e0d97c59b322 +F ext/fiddle/index.md 08d25ec6fe2a56923e8ea6e5d6c80907bf3a60f9c40a6841a8f402e402dd5f22 F ext/fts1/README.txt 20ac73b006a70bcfd80069bdaf59214b6cf1db5e F ext/fts1/ft_hash.c 3927bd880e65329bdc6f506555b228b28924921b F ext/fts1/ft_hash.h 06df7bba40dadd19597aa400a875dbc2fed705ea @@ -554,7 +557,7 @@ F src/random.c 097dc8b31b8fba5a9aca1697aeb9fd82078ec91be734c16bffda620ced7ab83c F src/resolve.c a4eb3c617027fd049b07432f3b942ea7151fa793a332a11a7d0f58c9539e104f F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92 F src/select.c 74060a09f66c0c056f3c61627e22cb484af0bbfa29d7d14dcf17c684742c15de -F src/shell.c.in 176cad562152cbbafe7ecc9c83c82850e2c3d0cf33ec0a52d67341d35c842f22 +F src/shell.c.in 1892f21aafee8eca543881ef429f6166386ca1ae0051252e91d1235bd6f4217b F src/sqlite.h.in d15c307939039086adca159dd340a94b79b69827e74c6d661f343eeeaefba896 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h a988810c9b21c0dc36dc7a62735012339dc76fc7ab448fb0792721d30eacb69d @@ -1954,8 +1957,11 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P d8b249e8cdf0babe1427d0587dbdc27a52ec06a5ef3a20dfb05a0ea4adb85858 -R 56c8d067b3c475439a951ae630953e32 -U drh -Z 99cc78493b68b2d09cacc03a9e60389c +P f7e1ceb5b59a876cfd04a8aac0ee2b322c970555b9c361b4953d711ef6596e37 +R f9ce230cf39758aaeb408ee00f09f455 +T *branch * fiddle +T *sym-fiddle * +T -sym-trunk * +U stephan +Z 33db0432b22b9541a19d442c2dec2c8e # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index e1be3622c7..9427d521e0 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f7e1ceb5b59a876cfd04a8aac0ee2b322c970555b9c361b4953d711ef6596e37 \ No newline at end of file +af9c21c9e0caf05adac7a9fcde39a9164c89f1c78b767b6fdd74a1405a3d373f \ No newline at end of file diff --git a/src/shell.c.in b/src/shell.c.in index cace8bf2f4..b46a00de66 100644 --- a/src/shell.c.in +++ b/src/shell.c.in @@ -229,6 +229,16 @@ static void setTextMode(FILE *file, int isOutput){ # define setTextMode(X,Y) #endif +/* +** When compiling with emcc (a.k.a. emscripten), we're building a +** WebAssembly (WASM) bundle and need to disable and rewire a few +** things. +*/ +#ifdef __EMSCRIPTEN__ +#define SQLITE_SHELL_WASM_MODE +#else +#undef SQLITE_SHELL_WASM_MODE +#endif /* True if the timer is enabled */ static int enableTimer = 0; @@ -691,6 +701,7 @@ static char *local_getline(char *zLine, FILE *in){ ** be freed by the caller or else passed back into this routine via the ** zPrior argument for reuse. */ +#ifndef SQLITE_SHELL_WASM_MODE static char *one_input_line(FILE *in, char *zPrior, int isContinuation){ char *zPrompt; char *zResult; @@ -710,7 +721,7 @@ static char *one_input_line(FILE *in, char *zPrior, int isContinuation){ } return zResult; } - +#endif /* !SQLITE_SHELL_WASM_MODE */ /* ** Return the value of a hexadecimal digit. Return -1 if the input @@ -1009,16 +1020,18 @@ INCLUDE test_windirent.h INCLUDE test_windirent.c #define dirent DIRENT #endif -INCLUDE ../ext/misc/shathree.c -INCLUDE ../ext/misc/fileio.c -INCLUDE ../ext/misc/completion.c -INCLUDE ../ext/misc/appendvfs.c INCLUDE ../ext/misc/memtrace.c +INCLUDE ../ext/misc/shathree.c INCLUDE ../ext/misc/uint.c INCLUDE ../ext/misc/decimal.c INCLUDE ../ext/misc/ieee754.c INCLUDE ../ext/misc/series.c INCLUDE ../ext/misc/regexp.c +#ifndef SQLITE_SHELL_WASM_MODE +INCLUDE ../ext/misc/fileio.c +INCLUDE ../ext/misc/completion.c +INCLUDE ../ext/misc/appendvfs.c +#endif #ifdef SQLITE_HAVE_ZLIB INCLUDE ../ext/misc/zipfile.c INCLUDE ../ext/misc/sqlar.c @@ -1149,8 +1162,18 @@ struct ShellState { char *zNonce; /* Nonce for temporary safe-mode excapes */ EQPGraph sGraph; /* Information for the graphical EXPLAIN QUERY PLAN */ ExpertInfo expert; /* Valid if previous command was ".expert OPT..." */ +#ifdef SQLITE_SHELL_WASM_MODE + struct { + const char * zInput; /* Input string from wasm/JS proxy */ + char const * zPos; /* Cursor pos into zInput */ + } wasm; +#endif }; +#ifdef SQLITE_SHELL_WASM_MODE +static ShellState shellState; +#endif + /* Allowed values for ShellState.autoEQP */ @@ -4991,14 +5014,16 @@ static void open_db(ShellState *p, int openFlags){ #ifndef SQLITE_OMIT_LOAD_EXTENSION sqlite3_enable_load_extension(p->db, 1); #endif - sqlite3_fileio_init(p->db, 0, 0); sqlite3_shathree_init(p->db, 0, 0); - sqlite3_completion_init(p->db, 0, 0); sqlite3_uint_init(p->db, 0, 0); sqlite3_decimal_init(p->db, 0, 0); sqlite3_regexp_init(p->db, 0, 0); sqlite3_ieee_init(p->db, 0, 0); sqlite3_series_init(p->db, 0, 0); +#ifndef SQLITE_SHELL_WASM_MODE + sqlite3_fileio_init(p->db, 0, 0); + sqlite3_completion_init(p->db, 0, 0); +#endif #if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_ENABLE_DBPAGE_VTAB) sqlite3_dbdata_init(p->db, 0, 0); #endif @@ -11467,6 +11492,39 @@ static void echo_group_input(ShellState *p, const char *zDo){ if( ShellHasFlag(p, SHFLG_Echo) ) utf8_printf(p->out, "%s\n", zDo); } +#ifdef SQLITE_SHELL_WASM_MODE +/* +** Alternate one_input_line() impl for wasm mode. This is not in the primary impl +** because we need the global shellState and cannot access it from that function +** without moving lots of code around (creating a larger/messier diff). +*/ +static char *one_input_line(FILE *in, char *zPrior, int isContinuation){ + /* Parse the next line from shellState.wasm.zInput. */ + const char *zBegin = shellState.wasm.zPos; + const char *z = zBegin; + char *zLine = 0; + int nZ = 0; + + UNUSED_PARAMETER(in); + UNUSED_PARAMETER(isContinuation); + if(!z || !*z){ + return 0; + } + while(*z && isspace(*z)) ++z; + zBegin = z; + for(; *z && '\n'!=*z; ++nZ, ++z){} + if(nZ>0 && '\r'==zBegin[nZ-1]){ + --nZ; + } + shellState.wasm.zPos = z; + zLine = realloc(zPrior, nZ+1); + shell_check_oom(zLine); + memcpy(zLine, zBegin, (size_t)nZ); + zLine[nZ] = 0; + return zLine; +} +#endif /* SQLITE_SHELL_WASM_MODE */ + /* ** Read input from *in and process it. If *in==0 then input ** is interactive - the user is typing it it. Otherwise, input @@ -11848,6 +11906,10 @@ static char *cmdline_option_value(int argc, char **argv, int i){ # endif #endif +#ifdef SQLITE_SHELL_WASM_MODE +# define main fiddle_main +#endif + #if SQLITE_SHELL_IS_UTF8 int SQLITE_CDECL main(int argc, char **argv){ #else @@ -11858,7 +11920,11 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){ sqlite3_uint64 mem_main_enter = sqlite3_memory_used(); #endif char *zErrMsg = 0; +#ifdef SQLITE_SHELL_WASM_MODE +# define data shellState +#else ShellState data; +#endif const char *zInitFile = 0; int i; int rc = 0; @@ -11874,8 +11940,13 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){ setBinaryMode(stdin, 0); setvbuf(stderr, 0, _IONBF, 0); /* Make sure stderr is unbuffered */ +#ifdef SQLITE_SHELL_WASM_MODE + stdin_is_interactive = 0; + stdout_is_console = 1; +#else stdin_is_interactive = isatty(0); stdout_is_console = isatty(1); +#endif #if !defined(_WIN32_WCE) if( getenv("SQLITE_DEBUG_BREAK") ){ @@ -12131,7 +12202,9 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){ #endif } data.out = stdout; +#ifndef SQLITE_SHELL_WASM_MODE sqlite3_appendvfs_init(0,0,0); +#endif /* Go ahead and open the database file if it already exists. If the ** file does not exist, delay opening it. This prevents empty database @@ -12397,6 +12470,9 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){ rc = process_input(&data); } } +#ifndef SQLITE_SHELL_WASM_MODE + /* 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. */ free(azCmd); set_table_name(&data, 0); if( data.db ){ @@ -12429,5 +12505,45 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){ (unsigned int)(sqlite3_memory_used()-mem_main_enter)); } #endif +#endif /* !SQLITE_SHELL_WASM_MODE */ return rc; } + + +#ifdef SQLITE_SHELL_WASM_MODE +/* +** Trivial exportable function for emscripten. Needs to be exported using: +** +** emcc ..flags... -sEXPORTED_FUNCTIONS=_fiddle_exec -sEXPORTED_RUNTIME_METHODS=ccall,cwrap +** +** (Note the underscore before the function name.) It processes zSql +** as if it were input to the sqlite3 shell and redirects all output +** to the wasm binding. +*/ +void fiddle_exec(char const * zSql){ + static int once = 0; + int rc = 0; + if(!once){ + /* Simulate an argv array for main() */ + static char * argv[] = {"fiddle", "-bail", "-safe"}; + rc = fiddle_main((int)(sizeof(argv)/sizeof(argv[0])), argv); + once = rc ? -1 : 1; + memset(&shellState.wasm, 0, sizeof(shellState.wasm)); + printf( + "SQLite version %s %.19s\n" /*extra-version-info*/, + sqlite3_libversion(), sqlite3_sourceid() + ); + puts("WASM shell"); + puts("Enter \".help\" for usage hints."); + puts("Connected to a transient in-memory database."); + } + if(once<0){ + puts("DB init failed. Not executing SQL."); + }else if(zSql && *zSql){ + shellState.wasm.zInput = zSql; + shellState.wasm.zPos = zSql; + process_input(&shellState); + memset(&shellState.wasm, 0, sizeof(shellState.wasm)); + } +} +#endif /* SQLITE_SHELL_WASM_MODE */ From 9f69b9411e9425e8d0be06f7c46598369dd87869 Mon Sep 17 00:00:00 2001 From: stephan Date: Wed, 18 May 2022 17:22:02 +0000 Subject: [PATCH 02/19] Increased default size of the fiddle output area, changed the .nullvalue default in the input area, and minor CSS tweaks. FossilOrigin-Name: 281aaae73167828bdf0bb2c07f83622475ab29b5755ac7fb8584c8e919c0a09b --- ext/fiddle/fiddle.in.html | 7 +++++-- manifest | 15 ++++++--------- manifest.uuid | 2 +- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/ext/fiddle/fiddle.in.html b/ext/fiddle/fiddle.in.html index ddd7d6984c..6df7ae7be7 100644 --- a/ext/fiddle/fiddle.in.html +++ b/ext/fiddle/fiddle.in.html @@ -50,6 +50,9 @@ .button-bar button { margin: 0.25em 1em; } + label { + cursor: pointer; + } @@ -62,7 +65,7 @@
- +
diff --git a/manifest b/manifest index 2cc14ec5e2..b3746c5eaf 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Initial\sversion\sof\san\ssqlfiddle-style\sapplication\susing\sa\sWASM\sbuild\sof\sthe\ssqlite3\sshell. -D 2022-05-18T17:14:24.622 +C Increased\sdefault\ssize\sof\sthe\sfiddle\soutput\sarea,\schanged\sthe\s.nullvalue\sdefault\sin\sthe\sinput\sarea,\sand\sminor\sCSS\stweaks. +D 2022-05-18T17:22:02.563 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -56,7 +56,7 @@ F ext/expert/sqlite3expert.c 6ca30d73b9ed75bd56d6e0d7f2c962d2affaa72c505458619d0 F ext/expert/sqlite3expert.h ca81efc2679a92373a13a3e76a6138d0310e32be53d6c3bfaedabd158ea8969b F ext/expert/test_expert.c d56c194b769bdc90cf829a14c9ecbc1edca9c850b837a4d0b13be14095c32a72 F ext/fiddle/Makefile ea647919e6ac4b50edde1490f60ee87e8ccd75141e4aa650718c6f28eb323bbc -F ext/fiddle/fiddle.in.html 85db5e736f82fd2cae1c4f61b5af62239cc5db363b9eb6f4e383e0d97c59b322 +F ext/fiddle/fiddle.in.html 3659d42f050e8f6544f8b46bd56f39c81655b8f4c094ad1f753c74567b2cf7f2 F ext/fiddle/index.md 08d25ec6fe2a56923e8ea6e5d6c80907bf3a60f9c40a6841a8f402e402dd5f22 F ext/fts1/README.txt 20ac73b006a70bcfd80069bdaf59214b6cf1db5e F ext/fts1/ft_hash.c 3927bd880e65329bdc6f506555b228b28924921b @@ -1957,11 +1957,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P f7e1ceb5b59a876cfd04a8aac0ee2b322c970555b9c361b4953d711ef6596e37 -R f9ce230cf39758aaeb408ee00f09f455 -T *branch * fiddle -T *sym-fiddle * -T -sym-trunk * +P af9c21c9e0caf05adac7a9fcde39a9164c89f1c78b767b6fdd74a1405a3d373f +R 3b664192bd5ef6de339309209f084d85 U stephan -Z 33db0432b22b9541a19d442c2dec2c8e +Z f2dd4c4723165b12480a254a01ad4fae # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 9427d521e0..daed1e0943 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -af9c21c9e0caf05adac7a9fcde39a9164c89f1c78b767b6fdd74a1405a3d373f \ No newline at end of file +281aaae73167828bdf0bb2c07f83622475ab29b5755ac7fb8584c8e919c0a09b \ No newline at end of file From 8ae45e4c6bce027c8b8e721f7d4b79854f4fb3a0 Mon Sep 17 00:00:00 2001 From: stephan Date: Wed, 18 May 2022 17:40:19 +0000 Subject: [PATCH 03/19] The fiddle input/output areas now stretch and shrink as needed to account for their available space. FossilOrigin-Name: 4eec05457fabe8248b8fd48d6187e772b69429ed64e99f02d0ad6b1230b5835e --- ext/fiddle/fiddle.in.html | 7 +++++-- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 12 insertions(+), 9 deletions(-) diff --git a/ext/fiddle/fiddle.in.html b/ext/fiddle/fiddle.in.html index 6df7ae7be7..a86f07ef76 100644 --- a/ext/fiddle/fiddle.in.html +++ b/ext/fiddle/fiddle.in.html @@ -6,7 +6,10 @@ sqlite3 fiddle @@ -81,6 +85,7 @@ select * from t;
+
@@ -92,7 +97,6 @@ select * from t;
-
+ --> {{{ SCRIPT }}} diff --git a/ext/fiddle/module-post.js b/ext/fiddle/module-post.js new file mode 100644 index 0000000000..bc6f3b2b9f --- /dev/null +++ b/ext/fiddle/module-post.js @@ -0,0 +1,87 @@ +/* This is the --post-js file for emcc. It gets appended to the + generated fiddle.js. It should contain all app-level code. + + Maintenance achtung: do not call any wasm-bound functions from + outside of the onRuntimeInitialized() function. They are not + permitted to be called until after the module init is complete, + which does not happen until after this file is processed. Once that + init is finished, Module.onRuntimeInitialized() will be + triggered. All app-level init code should go into that callback or + be triggered via it. Calling wasm-bound functions before that + callback is run will trigger an assertion in the wasm environment. +*/ +window.Module.onRuntimeInitialized = function(){ + 'use strict'; + const Module = window.Module /* wasm module as set up by emscripten */; + delete Module.onRuntimeInitialized; + const taInput = document.querySelector('#input'); + const btnClearIn = document.querySelector('#btn-clear'); + document.querySelectorAll('button').forEach(function(e){ + e.removeAttribute('disabled'); + }); + btnClearIn.addEventListener('click',function(){ + taInput.value = ''; + },false); + // Ctrl-enter and shift-enter both run the current SQL. + taInput.addEventListener('keydown',function(ev){ + if((ev.ctrlKey || ev.shiftKey) && 13 === ev.keyCode){ + ev.preventDefault(); + ev.stopPropagation(); + btnRun.click(); + } + }, false); + const taOutput = document.querySelector('#output'); + const btnClearOut = document.querySelector('#btn-clear-output'); + btnClearOut.addEventListener('click',function(){ + taOutput.value = ''; + },false); + /* Sends the given text to the shell. If it's null or empty, this + is a no-op except that the very first call will initialize the + db and output an informational header. */ + const doExec = function f(sql){ + if(!f._) f._ = Module.cwrap('fiddle_exec', null, ['string']); + if(Module._isDead){ + Module.printErr("shell module has exit()ed. Cannot run SQL."); + return; + } + if(Module.config.autoClearOutput) taOutput.value=''; + f._(sql); + }; + const btnRun = document.querySelector('#btn-run'); + btnRun.addEventListener('click',function(){ + const sql = taInput.value.trim(); + if(sql){ + doExec(sql); + } + },false); + + document.querySelector('#opt-cb-sbs') + .addEventListener('change', function(){ + document.querySelector('#main-wrapper').classList[ + this.checked ? 'add' : 'remove' + ]('side-by-side'); + }, false); + document.querySelector('#btn-notes-caveats') + .addEventListener('click', function(){ + document.querySelector('#notes-caveats').remove(); + }, false); + + /* For each checkbox with data-config=X, set up a binding to + Module.config[X]. */ + document.querySelectorAll('input[type=checkbox][data-config]') + .forEach(function(e){ + e.checked = !!Module.config[e.dataset.config]; + e.addEventListener('change', function(){ + Module.config[this.dataset.config] = this.checked; + }, false); + }); + + /* For each button with data-cmd=X, map a click handler which + calls doExec(X). */ + const cmdClick = function(){doExec(this.dataset.cmd);}; + document.querySelectorAll('button[data-cmd]').forEach( + e => e.addEventListener('click', cmdClick, false) + ); + + doExec(null)/*sets up the db and outputs the header*/; +}; diff --git a/ext/fiddle/module-pre.js b/ext/fiddle/module-pre.js new file mode 100644 index 0000000000..23cb7983c6 --- /dev/null +++ b/ext/fiddle/module-pre.js @@ -0,0 +1,100 @@ +/* This is the --pre-js file for emcc. It gets prepended to the + generated fiddle.js. It should contain only code which is relevant + to the setup and initialization of the wasm module. */ +(function(){ + 'use strict'; + + /** + What follows is part of the emscripten core setup. Do not + modify it without understanding what it's doing. + */ + const statusElement = document.getElementById('status'); + const progressElement = document.getElementById('progress'); + const spinnerElement = document.getElementById('spinner'); + const Module = window.Module = { + /* Config object. Referenced by certain Module methods and + app-level code. */ + config: { + /* If true, the Module.print() impl will auto-scroll + the output widget to the bottom when it receives output, + else it won't. */ + autoScrollOutput: true, + /* If true, the output area will be cleared before each + command is run, else it will not. */ + autoClearOutput: false, + /* If true, Module.print() will echo its output to + the console, in addition to its normal output widget. */ + printToConsole: false, + }, + preRun: [], + postRun: [], + //onRuntimeInitialized: function(){}, + print: (function f() { + if(!f._){ + f._ = document.getElementById('output'); + } + f._.value = ''; // clear browser cache + return function(text) { + if(arguments.length > 1) text = Array.prototype.slice.call(arguments).join(' '); + // These replacements are necessary if you render to raw HTML + //text = text.replace(/&/g, "&"); + //text = text.replace(//g, ">"); + //text = text.replace('\n', '
', 'g'); + //console.log("arguments",arguments); + if(window.Module.config.printToConsole) console.log(text); + f._.value += text + "\n"; + if(window.Module.config.autoScrollOutput){ + f._.scrollTop = f._.scrollHeight; + } + }; + })(), + setStatus: function f(text) { + if(!f.last) f.last = { time: Date.now(), text: '' }; + if(text === f.last.text) return; + const m = text.match(/([^(]+)\((\d+(\.\d+)?)\/(\d+)\)/); + const now = Date.now(); + if(m && now - f.last.time < 30) return; // if this is a progress update, skip it if too soon + f.last.time = now; + f.last.text = text; + if(m) { + text = m[1]; + progressElement.value = parseInt(m[2])*100; + progressElement.max = parseInt(m[4])*100; + progressElement.hidden = false; + spinnerElement.hidden = false; + } else { + progressElement.value = null; + progressElement.max = null; + progressElement.hidden = true; + if(!text) spinnerElement.hidden = true; + } + statusElement.innerHTML = text; + }, + totalDependencies: 0, + monitorRunDependencies: function(left) { + this.totalDependencies = Math.max(this.totalDependencies, left); + this.setStatus(left + ? ('Preparing... (' + (this.totalDependencies-left) + + '/' + this.totalDependencies + ')') + : 'All downloads complete.'); + } + }; + Module.printErr = Module.print/*capture stderr output*/; + Module.setStatus('Downloading...'); + window.onerror = function(/*message, source, lineno, colno, error*/) { + const err = arguments[4]; + if(err && 'ExitStatus'==err.name){ + Module._isDead = true; + Module.printErr("FATAL ERROR:", err.message); + Module.printErr("Restarting the app requires reloading the page."); + const taOutput = document.querySelector('#output'); + if(taOutput) taOutput.classList.add('error'); + } + Module.setStatus('Exception thrown, see JavaScript console'); + spinnerElement.style.display = 'none'; + Module.setStatus = function(text) { + if(text) console.error('[post-exception status] ' + text); + }; + }; +})(); diff --git a/manifest b/manifest index 66bed235f6..33c3e8de43 100644 --- a/manifest +++ b/manifest @@ -1,9 +1,9 @@ -C Added\san\soption\sto\sauto-clear\sthe\soutput\sarea\sbefore\ssubmitting\sthe\sinput.\sExperimentally\sinverted\sthe\scolors\sin\sthe\sinput/output\sareas. -D 2022-05-19T09:22:16.127 +C Split\sthe\sfiddle\sJS\scode\sinto\sseparate\spre-/post-init\sfiles\sto\ssimplify\sediting.\semcc\swill\scombine\sthese\sinto\sthe\sfinal\sfiddle.js,\sso\sthe\snumber\sof\soutput\sdeliverables\sdoes\snot\schange. +D 2022-05-19T09:55:14.804 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 -F Makefile.in 92890acbab78c76f32ebb1ad50b961c3fc413f7b05052663c8b17d1b7f74a697 +F Makefile.in 7835a8858609cd5f40b84e86cca78bd2c25c54f2e8b22fa76b16acf83509cb63 F Makefile.linux-gcc f609543700659711fbd230eced1f01353117621dccae7b9fb70daa64236c5241 F Makefile.msc b28a8a7a977e7312f6859f560348e1eb110c21bd6cf9fab0d16537c0a514eef3 F README.md 8b8df9ca852aeac4864eb1e400002633ee6db84065bd01b78c33817f97d31f5e @@ -56,8 +56,10 @@ F ext/expert/sqlite3expert.c 6ca30d73b9ed75bd56d6e0d7f2c962d2affaa72c505458619d0 F ext/expert/sqlite3expert.h ca81efc2679a92373a13a3e76a6138d0310e32be53d6c3bfaedabd158ea8969b F ext/expert/test_expert.c d56c194b769bdc90cf829a14c9ecbc1edca9c850b837a4d0b13be14095c32a72 F ext/fiddle/Makefile ea647919e6ac4b50edde1490f60ee87e8ccd75141e4aa650718c6f28eb323bbc -F ext/fiddle/fiddle.in.html 05192302452a1ff410a12de04d10802c89fd90c67d2e7a0983cca599b78d802d +F ext/fiddle/fiddle.in.html 69f8eeb8dc22cbaca2c890ed689d65dd8ad00e896b1a29caae8a22893fc51d8e F ext/fiddle/index.md d9c1c308d8074341bc3b11d1d39073cd77754cb3ca9aeb949f23fdd8323d81cf +F ext/fiddle/module-post.js 8d62f2199cb367267b7799f259c43673f43578f788f30e106a17b2eccbc8a918 +F ext/fiddle/module-pre.js 31661050c461fa05fbaa564e5369795eed8957458ea81fd2038157d852ff93c8 F ext/fts1/README.txt 20ac73b006a70bcfd80069bdaf59214b6cf1db5e F ext/fts1/ft_hash.c 3927bd880e65329bdc6f506555b228b28924921b F ext/fts1/ft_hash.h 06df7bba40dadd19597aa400a875dbc2fed705ea @@ -1957,8 +1959,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 6661d60527820417bbfd01c782d242c5190252ea703fc6f56376537d5c8f6a1e -R 1ba355c6c9a1901c14ddac3fca9f90fb +P 1a1e4e7fdbd0ec61218c3a311164086316d825181f3fc1c1ec235b63488746ef +R 845cc95de5a1a485fbec7d915e3ef826 U stephan -Z 350abcb9556383a2d29c463740d62bfd +Z 439fa3de2a51242095eb61aca5099555 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index a70a303356..565d54b618 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -1a1e4e7fdbd0ec61218c3a311164086316d825181f3fc1c1ec235b63488746ef \ No newline at end of file +d3d8ea011868bcfa11bb3fe2db78eea6e77ac1005534d9c091f9a81e03f0a7e6 \ No newline at end of file From 618a375e9f12e78ea0c2449bcf5ed7a769fc6796 Mon Sep 17 00:00:00 2001 From: stephan Date: Thu, 19 May 2022 10:24:50 +0000 Subject: [PATCH 12/19] #if'd out the '.log' command in WASM builds. Cleaned up the user-visible parts of the WASM module initialization. FossilOrigin-Name: b5fa12f824690c1022e4d69b0f5c3949324b311557a7412810741731db7e2cce --- ext/fiddle/fiddle.in.html | 48 ++++++++++++++++++++++++++++----------- ext/fiddle/module-post.js | 40 ++++++++++++++++++++------------ ext/fiddle/module-pre.js | 9 ++++---- manifest | 18 +++++++-------- manifest.uuid | 2 +- src/shell.c.in | 4 ++++ 6 files changed, 79 insertions(+), 42 deletions(-) diff --git a/ext/fiddle/fiddle.in.html b/ext/fiddle/fiddle.in.html index a9c2a57321..b78019565a 100644 --- a/ext/fiddle/fiddle.in.html +++ b/ext/fiddle/fiddle.in.html @@ -5,13 +5,14 @@ sqlite3 fiddle
sqlite3 fiddle
-
emscripten
+
+
+
Initializing app...
+
+ On a slow internet connection this may take a moment. If this + message displays for "a long time", intialization may have + failed and the JavaScript console may contain clues as to why. +
+
Downloading...
-
+
Options
@@ -120,7 +142,7 @@
-
+
- - - + + +
- +
-
+
Notes and Caveats diff --git a/ext/fiddle/module-post.js b/ext/fiddle/module-post.js index bc6f3b2b9f..41dfa35769 100644 --- a/ext/fiddle/module-post.js +++ b/ext/fiddle/module-post.js @@ -14,11 +14,23 @@ window.Module.onRuntimeInitialized = function(){ 'use strict'; const Module = window.Module /* wasm module as set up by emscripten */; delete Module.onRuntimeInitialized; - const taInput = document.querySelector('#input'); - const btnClearIn = document.querySelector('#btn-clear'); - document.querySelectorAll('button').forEach(function(e){ - e.removeAttribute('disabled'); - }); + + /* querySelectorAll() proxy */ + const EAll = function(/*[element=document,] cssSelector*/){ + return (arguments.length>1 ? arguments[0] : document) + .querySelectorAll(arguments[arguments.length-1]); + }; + /* querySelector() proxy */ + const E = function(/*[element=document,] cssSelector*/){ + return (arguments.length>1 ? arguments[0] : document) + .querySelector(arguments[arguments.length-1]); + }; + + // Unhide all elements which start out hidden + EAll('.initially-hidden').forEach((e)=>e.classList.remove('initially-hidden')); + + const taInput = E('#input'); + const btnClearIn = E('#btn-clear'); btnClearIn.addEventListener('click',function(){ taInput.value = ''; },false); @@ -30,8 +42,8 @@ window.Module.onRuntimeInitialized = function(){ btnRun.click(); } }, false); - const taOutput = document.querySelector('#output'); - const btnClearOut = document.querySelector('#btn-clear-output'); + const taOutput = E('#output'); + const btnClearOut = E('#btn-clear-output'); btnClearOut.addEventListener('click',function(){ taOutput.value = ''; },false); @@ -47,7 +59,7 @@ window.Module.onRuntimeInitialized = function(){ if(Module.config.autoClearOutput) taOutput.value=''; f._(sql); }; - const btnRun = document.querySelector('#btn-run'); + const btnRun = E('#btn-run'); btnRun.addEventListener('click',function(){ const sql = taInput.value.trim(); if(sql){ @@ -55,20 +67,20 @@ window.Module.onRuntimeInitialized = function(){ } },false); - document.querySelector('#opt-cb-sbs') + E('#opt-cb-sbs') .addEventListener('change', function(){ - document.querySelector('#main-wrapper').classList[ + E('#main-wrapper').classList[ this.checked ? 'add' : 'remove' ]('side-by-side'); }, false); - document.querySelector('#btn-notes-caveats') + E('#btn-notes-caveats') .addEventListener('click', function(){ - document.querySelector('#notes-caveats').remove(); + E('#notes-caveats').remove(); }, false); /* For each checkbox with data-config=X, set up a binding to Module.config[X]. */ - document.querySelectorAll('input[type=checkbox][data-config]') + EAll('input[type=checkbox][data-config]') .forEach(function(e){ e.checked = !!Module.config[e.dataset.config]; e.addEventListener('change', function(){ @@ -79,7 +91,7 @@ window.Module.onRuntimeInitialized = function(){ /* For each button with data-cmd=X, map a click handler which calls doExec(X). */ const cmdClick = function(){doExec(this.dataset.cmd);}; - document.querySelectorAll('button[data-cmd]').forEach( + EAll('button[data-cmd]').forEach( e => e.addEventListener('click', cmdClick, false) ); diff --git a/ext/fiddle/module-pre.js b/ext/fiddle/module-pre.js index 23cb7983c6..67c6f5a9a0 100644 --- a/ext/fiddle/module-pre.js +++ b/ext/fiddle/module-pre.js @@ -64,12 +64,11 @@ progressElement.hidden = false; spinnerElement.hidden = false; } else { - progressElement.value = null; - progressElement.max = null; - progressElement.hidden = true; - if(!text) spinnerElement.hidden = true; + progressElement.remove(); + if(!text) spinnerElement.remove(); } - statusElement.innerHTML = text; + if(text) statusElement.innerText = text; + else statusElement.remove(); }, totalDependencies: 0, monitorRunDependencies: function(left) { diff --git a/manifest b/manifest index 33c3e8de43..eb4115d318 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Split\sthe\sfiddle\sJS\scode\sinto\sseparate\spre-/post-init\sfiles\sto\ssimplify\sediting.\semcc\swill\scombine\sthese\sinto\sthe\sfinal\sfiddle.js,\sso\sthe\snumber\sof\soutput\sdeliverables\sdoes\snot\schange. -D 2022-05-19T09:55:14.804 +C #if'd\sout\sthe\s'.log'\scommand\sin\sWASM\sbuilds.\sCleaned\sup\sthe\suser-visible\sparts\sof\sthe\sWASM\smodule\sinitialization. +D 2022-05-19T10:24:50.097 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -56,10 +56,10 @@ F ext/expert/sqlite3expert.c 6ca30d73b9ed75bd56d6e0d7f2c962d2affaa72c505458619d0 F ext/expert/sqlite3expert.h ca81efc2679a92373a13a3e76a6138d0310e32be53d6c3bfaedabd158ea8969b F ext/expert/test_expert.c d56c194b769bdc90cf829a14c9ecbc1edca9c850b837a4d0b13be14095c32a72 F ext/fiddle/Makefile ea647919e6ac4b50edde1490f60ee87e8ccd75141e4aa650718c6f28eb323bbc -F ext/fiddle/fiddle.in.html 69f8eeb8dc22cbaca2c890ed689d65dd8ad00e896b1a29caae8a22893fc51d8e +F ext/fiddle/fiddle.in.html fc5bb8e6c13cac9880dfb41eceed3ff031d51d2a73bf66da51e5cc171e1ee28c F ext/fiddle/index.md d9c1c308d8074341bc3b11d1d39073cd77754cb3ca9aeb949f23fdd8323d81cf -F ext/fiddle/module-post.js 8d62f2199cb367267b7799f259c43673f43578f788f30e106a17b2eccbc8a918 -F ext/fiddle/module-pre.js 31661050c461fa05fbaa564e5369795eed8957458ea81fd2038157d852ff93c8 +F ext/fiddle/module-post.js 5d0eafba848a3e129c46ab1e1af99dcc7e8b7fc207f86ad05c5f45079cca9b6d +F ext/fiddle/module-pre.js 7c093908bd7768c96fb812e5fc1f15073ab129527fa2124a6f3e5076455761ed F ext/fts1/README.txt 20ac73b006a70bcfd80069bdaf59214b6cf1db5e F ext/fts1/ft_hash.c 3927bd880e65329bdc6f506555b228b28924921b F ext/fts1/ft_hash.h 06df7bba40dadd19597aa400a875dbc2fed705ea @@ -559,7 +559,7 @@ F src/random.c 097dc8b31b8fba5a9aca1697aeb9fd82078ec91be734c16bffda620ced7ab83c F src/resolve.c a4eb3c617027fd049b07432f3b942ea7151fa793a332a11a7d0f58c9539e104f F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92 F src/select.c 74060a09f66c0c056f3c61627e22cb484af0bbfa29d7d14dcf17c684742c15de -F src/shell.c.in ce99ca3e14211ca8d3eb82ba012504422ef42a59e4abd38c9a08a9638aee8694 +F src/shell.c.in cc3e19b2d2eefbadc4139b016c097d6478eae01d14eca993368ee5cff8820fff F src/sqlite.h.in d15c307939039086adca159dd340a94b79b69827e74c6d661f343eeeaefba896 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h a988810c9b21c0dc36dc7a62735012339dc76fc7ab448fb0792721d30eacb69d @@ -1959,8 +1959,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 1a1e4e7fdbd0ec61218c3a311164086316d825181f3fc1c1ec235b63488746ef -R 845cc95de5a1a485fbec7d915e3ef826 +P d3d8ea011868bcfa11bb3fe2db78eea6e77ac1005534d9c091f9a81e03f0a7e6 +R d7744af6398d083bf2a1bc37b40874d9 U stephan -Z 439fa3de2a51242095eb61aca5099555 +Z 4e1f89c6494ab0a52794383c827e3145 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 565d54b618..e83553ea74 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -d3d8ea011868bcfa11bb3fe2db78eea6e77ac1005534d9c091f9a81e03f0a7e6 \ No newline at end of file +b5fa12f824690c1022e4d69b0f5c3949324b311557a7412810741731db7e2cce \ No newline at end of file diff --git a/src/shell.c.in b/src/shell.c.in index c892a25bef..9a0859293b 100644 --- a/src/shell.c.in +++ b/src/shell.c.in @@ -4353,7 +4353,9 @@ static const char *(azHelp[]) = { #if !defined(SQLITE_OMIT_LOAD_EXTENSION) && !defined(SQLITE_SHELL_WASM_MODE) ".load FILE ?ENTRY? Load an extension library", #endif +#ifndef SQLITE_SHELL_WASM_MODE ".log FILE|off Turn logging on or off. FILE can be stderr/stdout", +#endif ".mode MODE ?OPTIONS? Set output mode", " MODE is one of:", " ascii Columns/rows delimited by 0x1F and 0x1E", @@ -9386,6 +9388,7 @@ static int do_meta_command(char *zLine, ShellState *p){ }else #endif +#ifndef SQLITE_SHELL_WASM_MODE if( c=='l' && strncmp(azArg[0], "log", n)==0 ){ failIfSafeMode(p, "cannot run .log in safe mode"); if( nArg!=2 ){ @@ -9397,6 +9400,7 @@ static int do_meta_command(char *zLine, ShellState *p){ p->pLog = output_file_open(zFile, 0); } }else +#endif if( c=='m' && strncmp(azArg[0], "mode", n)==0 ){ const char *zMode = 0; From 403445be23d35991b4675b7590e84a28c850fc15 Mon Sep 17 00:00:00 2001 From: stephan Date: Thu, 19 May 2022 10:38:54 +0000 Subject: [PATCH 13/19] Ensure that the output area is cleared of any init-time messages which the emscripten bootstrapping process emits when downloading of the wasm module is slow. FossilOrigin-Name: 1d8d0593573f9fc8e0990a292a4b3317d8a4c323d60514d0768543dd65c24d1e --- ext/fiddle/module-post.js | 1 + ext/fiddle/module-pre.js | 20 +++++++++++++------- manifest | 14 +++++++------- manifest.uuid | 2 +- 4 files changed, 22 insertions(+), 15 deletions(-) diff --git a/ext/fiddle/module-post.js b/ext/fiddle/module-post.js index 41dfa35769..5f91d0ca25 100644 --- a/ext/fiddle/module-post.js +++ b/ext/fiddle/module-post.js @@ -95,5 +95,6 @@ window.Module.onRuntimeInitialized = function(){ e => e.addEventListener('click', cmdClick, false) ); + Module.print(null/*clear any output generated by the init process*/); doExec(null)/*sets up the db and outputs the header*/; }; diff --git a/ext/fiddle/module-pre.js b/ext/fiddle/module-pre.js index 67c6f5a9a0..9e9c88f22e 100644 --- a/ext/fiddle/module-pre.js +++ b/ext/fiddle/module-pre.js @@ -30,10 +30,13 @@ postRun: [], //onRuntimeInitialized: function(){}, print: (function f() { - if(!f._){ - f._ = document.getElementById('output'); - } - f._.value = ''; // clear browser cache + /* Maintenance reminder: we currently require/expect a textarea + output element. It might be nice to extend this to behave + differently if the output element is a non-textarea element, + in which case it would need to append the given text as a TEXT + node and add a line break. */ + const outputElem = document.getElementById('output'); + outputElem.value = ''; // clear browser cache return function(text) { if(arguments.length > 1) text = Array.prototype.slice.call(arguments).join(' '); // These replacements are necessary if you render to raw HTML @@ -41,11 +44,14 @@ //text = text.replace(//g, ">"); //text = text.replace('\n', '
', 'g'); - //console.log("arguments",arguments); + if(null===text){/*special case: clear output*/ + outputElem.value = ''; + return; + } if(window.Module.config.printToConsole) console.log(text); - f._.value += text + "\n"; + outputElem.value += text + "\n"; if(window.Module.config.autoScrollOutput){ - f._.scrollTop = f._.scrollHeight; + outputElem.scrollTop = outputElem.scrollHeight; } }; })(), diff --git a/manifest b/manifest index eb4115d318..45fdebe913 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C #if'd\sout\sthe\s'.log'\scommand\sin\sWASM\sbuilds.\sCleaned\sup\sthe\suser-visible\sparts\sof\sthe\sWASM\smodule\sinitialization. -D 2022-05-19T10:24:50.097 +C Ensure\sthat\sthe\soutput\sarea\sis\scleared\sof\sany\sinit-time\smessages\swhich\sthe\semscripten\sbootstrapping\sprocess\semits\swhen\sdownloading\sof\sthe\swasm\smodule\sis\sslow. +D 2022-05-19T10:38:54.185 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -58,8 +58,8 @@ F ext/expert/test_expert.c d56c194b769bdc90cf829a14c9ecbc1edca9c850b837a4d0b13be F ext/fiddle/Makefile ea647919e6ac4b50edde1490f60ee87e8ccd75141e4aa650718c6f28eb323bbc F ext/fiddle/fiddle.in.html fc5bb8e6c13cac9880dfb41eceed3ff031d51d2a73bf66da51e5cc171e1ee28c F ext/fiddle/index.md d9c1c308d8074341bc3b11d1d39073cd77754cb3ca9aeb949f23fdd8323d81cf -F ext/fiddle/module-post.js 5d0eafba848a3e129c46ab1e1af99dcc7e8b7fc207f86ad05c5f45079cca9b6d -F ext/fiddle/module-pre.js 7c093908bd7768c96fb812e5fc1f15073ab129527fa2124a6f3e5076455761ed +F ext/fiddle/module-post.js 5295dfb2bd744cb0ad03d219e8e14123b1bb8ad39054f8b65c3358df4d746cd2 +F ext/fiddle/module-pre.js baff3e5f693db09f693af0bf398c0c89cdef04bdc3ffb6ad4ed02775077fdea4 F ext/fts1/README.txt 20ac73b006a70bcfd80069bdaf59214b6cf1db5e F ext/fts1/ft_hash.c 3927bd880e65329bdc6f506555b228b28924921b F ext/fts1/ft_hash.h 06df7bba40dadd19597aa400a875dbc2fed705ea @@ -1959,8 +1959,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P d3d8ea011868bcfa11bb3fe2db78eea6e77ac1005534d9c091f9a81e03f0a7e6 -R d7744af6398d083bf2a1bc37b40874d9 +P b5fa12f824690c1022e4d69b0f5c3949324b311557a7412810741731db7e2cce +R e7797da2d1a4378761bd408e0f019d9d U stephan -Z 4e1f89c6494ab0a52794383c827e3145 +Z 2f01ae6f2a6a94715d9eed3abad05b24 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index e83553ea74..cb51321570 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b5fa12f824690c1022e4d69b0f5c3949324b311557a7412810741731db7e2cce \ No newline at end of file +1d8d0593573f9fc8e0990a292a4b3317d8a4c323d60514d0768543dd65c24d1e \ No newline at end of file From 6da6f31cca0e3a4cdb2330b7f51cc0bfe540f21f Mon Sep 17 00:00:00 2001 From: stephan Date: Thu, 19 May 2022 10:58:59 +0000 Subject: [PATCH 14/19] fiddle make target now accepts fiddle_cflags=... from the CLI to overrid -Ox and such for one-off builds. FossilOrigin-Name: 4609a4f8626ae3d8179cae27e391bd06ffda18e9ef9e1b78745b36c7e8dd25db --- Makefile.in | 9 ++++++--- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 13 insertions(+), 10 deletions(-) diff --git a/Makefile.in b/Makefile.in index 158d174d31..d2b5fc3474 100644 --- a/Makefile.in +++ b/Makefile.in @@ -1518,7 +1518,6 @@ sqlite3.dll: $(REAL_LIBOBJ) sqlite3.def # fiddle section # fiddle_dir = ext/fiddle -fiddle_tmpl = $(fiddle_dir)/fiddle.in.html fiddle_html = $(fiddle_dir)/fiddle.html fiddle_generated = $(fiddle_html) \ $(fiddle_dir)/fiddle.js \ @@ -1537,8 +1536,12 @@ emcc_flags = $(emcc_opt) \ -sEXIT_RUNTIME=1 \ --pre-js $(fiddle_dir)/module-pre.js \ --post-js $(fiddle_dir)/module-post.js \ - --shell-file $(fiddle_tmpl) -$(fiddle_html): Makefile sqlite3.c shell.c $(fiddle_tmpl) \ + --shell-file $(fiddle_dir)/fiddle.in.html \ + $(fiddle_cflags) +# $(fiddle_cflags) is intended to be passed to make via the CLI in +# order to override, e.g., -Ox for one-off builds. +$(fiddle_html): Makefile sqlite3.c shell.c \ + $(fiddle_dir)/fiddle.in.html \ $(fiddle_dir)/module-pre.js $(fiddle_dir)/module-post.js emcc -o $@ $(emcc_flags) sqlite3.c shell.c fiddle: $(fiddle_html) diff --git a/manifest b/manifest index 45fdebe913..0a5f20a3c7 100644 --- a/manifest +++ b/manifest @@ -1,9 +1,9 @@ -C Ensure\sthat\sthe\soutput\sarea\sis\scleared\sof\sany\sinit-time\smessages\swhich\sthe\semscripten\sbootstrapping\sprocess\semits\swhen\sdownloading\sof\sthe\swasm\smodule\sis\sslow. -D 2022-05-19T10:38:54.185 +C fiddle\smake\starget\snow\saccepts\sfiddle_cflags=...\sfrom\sthe\sCLI\sto\soverrid\s-Ox\sand\ssuch\sfor\sone-off\sbuilds. +D 2022-05-19T10:58:59.923 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 -F Makefile.in 7835a8858609cd5f40b84e86cca78bd2c25c54f2e8b22fa76b16acf83509cb63 +F Makefile.in 04cd03b6d3b1f1ec84b5b052f37d0a8708000f3d9584e6106f1b8e2e1f559987 F Makefile.linux-gcc f609543700659711fbd230eced1f01353117621dccae7b9fb70daa64236c5241 F Makefile.msc b28a8a7a977e7312f6859f560348e1eb110c21bd6cf9fab0d16537c0a514eef3 F README.md 8b8df9ca852aeac4864eb1e400002633ee6db84065bd01b78c33817f97d31f5e @@ -1959,8 +1959,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P b5fa12f824690c1022e4d69b0f5c3949324b311557a7412810741731db7e2cce -R e7797da2d1a4378761bd408e0f019d9d +P 1d8d0593573f9fc8e0990a292a4b3317d8a4c323d60514d0768543dd65c24d1e +R 95e0243279f406591d2490a8625a64de U stephan -Z 2f01ae6f2a6a94715d9eed3abad05b24 +Z 342f02945f9525abd872463c70c813a2 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index cb51321570..1b25cdb1c6 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -1d8d0593573f9fc8e0990a292a4b3317d8a4c323d60514d0768543dd65c24d1e \ No newline at end of file +4609a4f8626ae3d8179cae27e391bd06ffda18e9ef9e1b78745b36c7e8dd25db \ No newline at end of file From 38240592ad483954d9d10055dec39ebd1af504ce Mon Sep 17 00:00:00 2001 From: stephan Date: Thu, 19 May 2022 15:58:13 +0000 Subject: [PATCH 15/19] Numerous layout tweaks, the most significant being that the layout now adapts to the window size. Swapped positions of the input/output areas. This version supports, by uncommenting a few bits, a jquery.terminal-based view but alternatives to that 300kb dependency are still under investigation. FossilOrigin-Name: 1aad3642c9fc14c25223628a309d84decc8d73a123e42d6efdc36d855b5b0666 --- ext/fiddle/fiddle.in.html | 142 +++++++++++++++++++++----------------- ext/fiddle/module-post.js | 129 ++++++++++++++++++++++++++++++++-- ext/fiddle/module-pre.js | 3 +- manifest | 16 ++--- manifest.uuid | 2 +- 5 files changed, 212 insertions(+), 80 deletions(-) diff --git a/ext/fiddle/fiddle.in.html b/ext/fiddle/fiddle.in.html index b78019565a..a14bf5b4b4 100644 --- a/ext/fiddle/fiddle.in.html +++ b/ext/fiddle/fiddle.in.html @@ -4,6 +4,8 @@ sqlite3 fiddle + -
sqlite3 fiddle
+
sqlite3 fiddle
Initializing app...
@@ -123,75 +154,56 @@
-
- Options -
- - - - - - - - - - - - -
-
-
-
- -
- - - +
+ + + +
+
+
+ +
+ +
-
- -
- -
-
-
-
-
- Notes and Caveats - -
-

- This JavaScript application runs a C application which has been - compiled into WASM (Web Assembly). As such, it has certain - limitations. Those include, but are not limited to: -

-
    -
  • It cannot recover after a call to - exit(). If the native code triggers - an exit, reloading the page is the only way to restart - the application. (Making the app restartable without reloading - the page would require significant surgery in the C code.) -
  • -
  • It cannot perform any file I/O, and running - any command which attempts to do so might trigger an - exit(). -
  • -
  • A number of dot-commands available in the CLI shell are - explicitly removed from this version of the shell. -
  • -
-
+