@amritk/nish-x86_64-linux 0.18.0 → 0.21.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (104) hide show
  1. package/INSTALL.md +58 -28
  2. package/bin/nish +0 -0
  3. package/docs/AI.md +2759 -0
  4. package/package.json +3 -2
  5. package/runtime/browser.d.ts +14 -0
  6. package/runtime/browser.mjs +88 -0
  7. package/runtime/core/arrays.d.ts +18 -0
  8. package/runtime/core/arrays.mjs +125 -0
  9. package/runtime/core/checks.mjs +20 -0
  10. package/runtime/core/host.d.ts +70 -0
  11. package/runtime/core/host.mjs +311 -0
  12. package/runtime/core/numbers.d.ts +53 -0
  13. package/runtime/core/numbers.mjs +316 -0
  14. package/runtime/core/result.d.ts +41 -0
  15. package/runtime/core/result.mjs +127 -0
  16. package/runtime/core/strings.d.ts +14 -0
  17. package/runtime/core/strings.mjs +169 -0
  18. package/runtime/core.d.ts +9 -0
  19. package/runtime/core.mjs +55 -0
  20. package/runtime/host.d.ts +6 -0
  21. package/runtime/nish.d.ts +99 -5
  22. package/runtime/nish.h +289 -19
  23. package/runtime/nish.mjs +39 -3
  24. package/runtime/node.mjs +383 -0
  25. package/runtime/runtime-aes.c +490 -0
  26. package/runtime/runtime-bytes.c +401 -0
  27. package/runtime/runtime-cross.c +366 -0
  28. package/runtime/runtime-host.c +8 -7
  29. package/runtime/runtime-net.c +93 -34
  30. package/runtime/runtime-os.c +214 -16
  31. package/runtime/runtime-parallel.c +590 -107
  32. package/runtime/runtime-simd.c +235 -11
  33. package/runtime/runtime-term.c +504 -0
  34. package/runtime/runtime-wasm.c +5 -14
  35. package/runtime/runtime.c +257 -17
  36. package/runtime/shim.mjs +6 -915
  37. package/runtime/sqlite/LICENSE.md +85 -0
  38. package/runtime/sqlite/README.md +45 -0
  39. package/runtime/sqlite/nish-sqlite.c +359 -0
  40. package/runtime/sqlite/sqlite3.c +271131 -0
  41. package/runtime/sqlite/sqlite3.h +14447 -0
  42. package/scripts/build.sh +437 -28
  43. package/std/LICENSE-fast-float +23 -0
  44. package/std/LICENSE-fdlibm +8 -0
  45. package/std/README.md +108 -58
  46. package/std/base64.ts +116 -0
  47. package/std/bytes.ts +419 -0
  48. package/std/cli.ts +328 -0
  49. package/std/collections.ts +6 -5
  50. package/std/crypto/LICENSE-crypt_blowfish +26 -0
  51. package/std/crypto/LICENSE-libsecp256k1 +19 -0
  52. package/std/crypto/aes.ts +238 -76
  53. package/std/crypto/base64url.ts +125 -0
  54. package/std/crypto/bcrypt.ts +760 -0
  55. package/std/crypto/chacha20poly1305.ts +43 -9
  56. package/std/crypto/ed25519.ts +840 -0
  57. package/std/crypto/hkdf.ts +304 -12
  58. package/std/crypto/hmac.ts +382 -54
  59. package/std/crypto/p256.ts +932 -61
  60. package/std/crypto/x25519.ts +55 -37
  61. package/std/crypto/x509-random.ts +71 -0
  62. package/std/crypto/x509.ts +20 -131
  63. package/std/json-tokenizer.ts +4237 -0
  64. package/std/json-typed.ts +1014 -0
  65. package/std/json-value.ts +1182 -0
  66. package/std/json.ts +1202 -34
  67. package/std/math.ts +608 -0
  68. package/std/net/buffer-pool.ts +151 -0
  69. package/std/net/hpack.ts +416 -112
  70. package/std/net/http-fields.ts +93 -0
  71. package/std/net/http1-server.ts +501 -62
  72. package/std/net/http1.ts +31 -6
  73. package/std/net/http2-tls.ts +112 -24
  74. package/std/net/http2.ts +333 -75
  75. package/std/net/http3-server.ts +261 -43
  76. package/std/net/http3.ts +187 -28
  77. package/std/net/postgres.ts +1875 -0
  78. package/std/net/prefork.ts +412 -0
  79. package/std/net/quic-listener.ts +108 -11
  80. package/std/net/quic-packet.ts +243 -82
  81. package/std/net/quic-recovery.ts +361 -30
  82. package/std/net/quic-stream.ts +424 -24
  83. package/std/net/quic.ts +519 -167
  84. package/std/net/router.ts +676 -0
  85. package/std/net/tls/codec.ts +426 -27
  86. package/std/net/tls/record-server.ts +478 -132
  87. package/std/net/tls/record.ts +133 -42
  88. package/std/net/tls/schedule.ts +464 -55
  89. package/std/net/tls/ticket.ts +610 -0
  90. package/std/net/tls-tcp.ts +196 -53
  91. package/std/net/tls.ts +1018 -260
  92. package/std/net/url.ts +571 -0
  93. package/std/random.ts +94 -0
  94. package/std/regex.ts +4274 -0
  95. package/std/sqlite.ts +391 -0
  96. package/std/term-io.ts +978 -0
  97. package/std/term-pixels.ts +874 -0
  98. package/std/term-probe.ts +459 -0
  99. package/std/term-rate.ts +993 -0
  100. package/std/term.ts +2453 -0
  101. package/std/text.ts +90 -7
  102. package/std/threads.ts +438 -14
  103. package/std/yaml-lines.ts +141 -0
  104. package/std/yaml.ts +4675 -0
@@ -0,0 +1,85 @@
1
+ License Information
2
+ ===================
3
+
4
+ SQLite Is Public Domain
5
+ -----------------------
6
+
7
+ The SQLite source code, including all of the files in the directories
8
+ listed in the bullets below are
9
+ [Public Domain](https://sqlite.org/copyright.html).
10
+ The authors have submitted written affidavits releasing their work to
11
+ the public for any use. Every byte of the public-domain code can be
12
+ traced back to the original authors. The files of this repository
13
+ that are public domain include the following:
14
+
15
+ * All of the primary SQLite source code files found in the
16
+ [src/ directory](https://sqlite.org/src/tree/src?type=tree&expand)
17
+ * All of the test cases and testing code in the
18
+ [test/ directory](https://sqlite.org/src/tree/test?type=tree&expand)
19
+ * All of the SQLite extension source code and test cases in the
20
+ [ext/ directory](https://sqlite.org/src/tree/ext?type=tree&expand)
21
+ * All code that ends up in the "sqlite3.c" and "sqlite3.h" build products
22
+ that actually implement the SQLite RDBMS.
23
+ * All of the code used to compile the
24
+ [command-line interface](https://sqlite.org/cli.html)
25
+ * All of the code used to build various utility programs such as
26
+ "sqldiff", "sqlite3_rsync", and "sqlite3_analyzer".
27
+
28
+
29
+ The public domain source files usually contain a header comment
30
+ similar to the following to make it clear that the software is
31
+ public domain.
32
+
33
+ > The author disclaims copyright to this source code. In place of
34
+ > a legal notice, here is a blessing:
35
+ >
36
+ > * May you do good and not evil.
37
+ > * May you find forgiveness for yourself and forgive others.
38
+ > * May you share freely, never taking more than you give.
39
+
40
+ Almost every file you find in this source repository will be
41
+ public domain. But there are a small number of exceptions:
42
+
43
+ Non-Public-Domain Code Included With This Source Repository AS A Convenience
44
+ ----------------------------------------------------------------------------
45
+
46
+ This repository contains a (relatively) small amount of non-public-domain
47
+ code used to help implement the configuration and build logic. In other
48
+ words, there are some non-public-domain files used to implement:
49
+
50
+ > ./configure && make
51
+
52
+ In all cases, the non-public-domain files included with this
53
+ repository have generous BSD-style licenses. So anyone is free to
54
+ use any of the code in this source repository for any purpose, though
55
+ attribution may be required to reuse or republish the configure and
56
+ build scripts. None of the non-public-domain code ever actually reaches
57
+ the build products, such as "sqlite3.c", however, so no attribution is
58
+ required to use SQLite itself. The non-public-domain code consists of
59
+ scripts used to help compile SQLite. The non-public-domain code is
60
+ technically not part of SQLite. The non-public-domain code is
61
+ included in this repository as a convenience to developers, so that those
62
+ who want to build SQLite do not need to go download a bunch of
63
+ third-party build scripts in order to compile SQLite.
64
+
65
+ Non-public-domain code included in this respository includes:
66
+
67
+ * The ["autosetup"](http://msteveb.github.io/autosetup/) configuration
68
+ system that is contained (mostly) in the autosetup/ directory, but also
69
+ includes the "./configure" script at the top-level of this archive.
70
+ Autosetup has a separate BSD-style license. See the
71
+ [autosetup/LICENSE](http://msteveb.github.io/autosetup/license/)
72
+ for details.
73
+
74
+ * There are BSD-style licenses on some of the configuration
75
+ software found in the legacy autoconf/ directory and its
76
+ subdirectories.
77
+
78
+ The following unix shell command can be run from the top-level
79
+ of this source repository in order to remove all non-public-domain
80
+ code:
81
+
82
+ > rm -rf configure autosetup autoconf
83
+
84
+ If you unpack this source repository and then run the command above, what
85
+ is left will be 100% public domain.
@@ -0,0 +1,45 @@
1
+ # runtime/sqlite/
2
+
3
+ The [SQLite](https://sqlite.org/) amalgamation, vendored so that a Nish program
4
+ that calls SQLite links it with no library installed on the system.
5
+
6
+ | | |
7
+ | --- | --- |
8
+ | Version | 3.54.1 (`SQLITE_SOURCE_ID` `2026-10-16 14:45:20 555e07ef…`) |
9
+ | From | <https://sqlite.org/2026/sqlite-amalgamation-3540100.zip> |
10
+ | SHA3-256 of the archive | `92281c86e2957f9b9305890f9ac04204caa7b677cc868dc326d942689df28e30` |
11
+ | SHA3-256 of `sqlite3.c` | `e2b869d3003b33c942b7dd7063604fbc53553e1b66609570df39b9b7b558ee81` |
12
+ | SHA3-256 of `sqlite3.h` | `15ef3f5dbc4a7a980f828fa0d1e473cee5a124e7bb77e9bc70fc0bfa3f9a2af8` |
13
+ | Taken | `sqlite3.c` and `sqlite3.h`, byte for byte; not `shell.c` or `sqlite3ext.h` |
14
+ | Vendored | 2026-10-24 |
15
+ | Licence | public domain ([sqlite.org/copyright.html](https://sqlite.org/copyright.html)); `LICENSE.md` is upstream's, from <https://sqlite.org/src/raw/LICENSE.md?ci=version-3.54.1> |
16
+
17
+ `sqlite3.c` and `sqlite3.h` are never edited. A change SQLite needs is a
18
+ compile-time option in `scripts/build.sh`, or code in a file of our own beside
19
+ them.
20
+
21
+ ## How it is linked
22
+
23
+ `scripts/build.sh` compiles every `*.c` here for a link whose IR declares an
24
+ `sqlite3_*` or `nishsqlite_*` function, and for no other link. The options are
25
+ in `build.sh`, under "SQLite's compile-time options". `NISH_SQLITE_CFLAGS` adds
26
+ to them (`docs/guide/using-nish/cli.md`). `nish --link` and `nish run` compile
27
+ these units once per recipe into an entry of the runtime cache of their own
28
+ (`src/compile.ts`, `cachedRuntime`). `src/run-cache.ts` reads this directory
29
+ for the units and the files the cache key fingerprints (`sqliteUnits`,
30
+ `sqliteFingerprint`), so a file added here needs no list updated.
31
+ `tests/run.js` ("sqlite-link") checks the two hashes above against the files.
32
+
33
+ ## Updating
34
+
35
+ 1. Download the new `sqlite-amalgamation-<NNNNNNN>.zip` from
36
+ <https://sqlite.org/download.html>. Check its SHA3-256 against the one on
37
+ that page.
38
+ 2. Copy `sqlite3.c` and `sqlite3.h` over the ones here, unchanged. Replace
39
+ `LICENSE.md` with the one tagged for that version, if it differs.
40
+ 3. Update the table above, the two file hashes included (`openssl dgst
41
+ -sha3-256 sqlite3.c sqlite3.h`), the version in `THIRD_PARTY_NOTICES.md`, and the
42
+ numbers in `tests/link/sqlite_link*/expected.out`.
43
+ 4. Run `node tests/run.js link`, `node tests/run.js sqlite-link`,
44
+ `WASI_SYSROOT=/usr node tests/run.js wasi` and the third-party-licence
45
+ section.
@@ -0,0 +1,359 @@
1
+ /* The C half of `nish/sqlite` (std/sqlite.ts): the handle tables, and one
2
+ * adapter per SQLite call that a Nish declaration cannot make by itself.
3
+ *
4
+ * A Nish program cannot hold an `sqlite3 *` in a value it exports, take an
5
+ * out-pointer (`sqlite3 **`) or name `SQLITE_TRANSIENT`, so this file keeps
6
+ * every connection and every prepared statement in a table and hands the
7
+ * program an `int32_t` handle into it. A handle is the slot's index in the low
8
+ * 16 bits and the slot's generation in the 15 above them, so it is never 0
9
+ * or negative. Freeing a slot moves its generation on, and a handle whose
10
+ * generation is not the slot's answers SQLITE_MISUSE, so a statement used
11
+ * after `finalize`, or after its database's `close`, is refused rather than
12
+ * reaching a freed pointer. A slot whose generation reaches 32,767, the
13
+ * generation's width, is retired rather than restarted at 1, so no handle
14
+ * ever names a slot twice and a stale handle can never alias a live one. A
15
+ * table that has retired or filled all 65,535 of its slots answers
16
+ * SQLITE_NOMEM, which takes some two billion opens or prepares.
17
+ *
18
+ * The tables are thread-local under --threads (`NISH_TLS`, ../nish.h). A
19
+ * connection and its statements belong to the thread that opened them: a
20
+ * handle passed to another thread names nothing there and answers
21
+ * SQLITE_MISUSE. That is also why the tables need no lock. SQLite is compiled
22
+ * SQLITE_THREADSAFE=2 under --threads (scripts/build.sh), which allows one
23
+ * connection per thread. A thread's tables are not freed when it exits.
24
+ *
25
+ * Nothing here allocates except a table growing (`slot_take`) and SQLite
26
+ * itself. Each adapter is a table load and the SQLite call, compiled to LTO
27
+ * bitcode (scripts/build.sh, `sqlite_units`), so it inlines into the program.
28
+ *
29
+ * Results follow SQLite: an `int32_t` result code, extended, because every
30
+ * connection is opened with SQLITE_OPEN_EXRESCODE. Two adapters answer a
31
+ * handle or a length when they succeed and the negated code when they fail.
32
+ * Text and blobs are bound SQLITE_TRANSIENT, so SQLite copies them, because
33
+ * the program lends its bytes for the length of one call
34
+ * (docs/LANGUAGE.md, "Calling C"). */
35
+
36
+ #include <stdint.h>
37
+ #include <stdlib.h>
38
+ #include <string.h>
39
+
40
+ #include "../nish.h"
41
+ #include "sqlite3.h"
42
+
43
+ typedef struct nishsqlite_slot {
44
+ void *p; /* the sqlite3 * or sqlite3_stmt *, NULL while free */
45
+ int32_t gen; /* 1..32767, the high bits of the slot's handle */
46
+ int32_t owner; /* a statement's database handle; 0 for a database */
47
+ int32_t next; /* the next free slot, oldest first; 0 ends the list */
48
+ } nishsqlite_slot;
49
+
50
+ typedef struct nishsqlite_table {
51
+ nishsqlite_slot *at; /* at[0] is never used, so no handle is 0 */
52
+ int32_t len;
53
+ int32_t cap;
54
+ int32_t head; /* the oldest free slot, 0 when none */
55
+ int32_t tail;
56
+ } nishsqlite_table;
57
+
58
+ #define NISH_SQLITE_INDEX 0xffff
59
+ #define NISH_SQLITE_GEN_MAX 0x7fff
60
+
61
+ static NISH_TLS nishsqlite_table nishsqlite_dbs;
62
+ static NISH_TLS nishsqlite_table nishsqlite_stmts;
63
+
64
+ /* What the last failed `nishsqlite_open` said, kept because the connection it
65
+ * came from is closed before the open answers. */
66
+ static NISH_TLS char nishsqlite_open_message[256];
67
+
68
+ static inline nishsqlite_slot *slot_of(nishsqlite_table *t, int32_t h) {
69
+ int32_t i = h & NISH_SQLITE_INDEX;
70
+ if (h <= 0 || i >= t->len) return NULL;
71
+ nishsqlite_slot *s = &t->at[i];
72
+ if (s->p == NULL || s->gen != (h >> 16)) return NULL;
73
+ return s;
74
+ }
75
+
76
+ static inline sqlite3 *db_of(int32_t h) {
77
+ nishsqlite_slot *s = slot_of(&nishsqlite_dbs, h);
78
+ return s ? (sqlite3 *)s->p : NULL;
79
+ }
80
+
81
+ static inline sqlite3_stmt *stmt_of(int32_t h) {
82
+ nishsqlite_slot *s = slot_of(&nishsqlite_stmts, h);
83
+ return s ? (sqlite3_stmt *)s->p : NULL;
84
+ }
85
+
86
+ /* A slot for `p`, and its handle; 0 when the table is full or cannot grow. */
87
+ static int32_t slot_take(nishsqlite_table *t, void *p, int32_t owner) {
88
+ int32_t i = t->head;
89
+ if (i != 0) {
90
+ t->head = t->at[i].next;
91
+ if (t->head == 0) t->tail = 0;
92
+ } else {
93
+ if (t->len == 0) t->len = 1;
94
+ if (t->len > NISH_SQLITE_INDEX) return 0;
95
+ if (t->len >= t->cap) {
96
+ int32_t cap = t->cap ? t->cap * 2 : 16;
97
+ nishsqlite_slot *at = realloc(t->at, (size_t)cap * sizeof *at);
98
+ if (at == NULL) return 0;
99
+ memset(at + t->cap, 0, (size_t)(cap - t->cap) * sizeof *at); /* at[0] stays empty */
100
+ t->at = at;
101
+ t->cap = cap;
102
+ }
103
+ i = t->len++;
104
+ t->at[i].gen = 1;
105
+ }
106
+ t->at[i].p = p;
107
+ t->at[i].owner = owner;
108
+ t->at[i].next = 0;
109
+ return (t->at[i].gen << 16) | i;
110
+ }
111
+
112
+ /* Frees the slot `h` names and moves its generation on, so `h` names nothing.
113
+ * A slot at the last generation is retired: it stays empty and off the free
114
+ * list, so its handles are never handed out again. */
115
+ static void slot_give(nishsqlite_table *t, int32_t h) {
116
+ int32_t i = h & NISH_SQLITE_INDEX;
117
+ nishsqlite_slot *s = &t->at[i];
118
+ s->p = NULL;
119
+ s->next = 0;
120
+ if (s->gen == NISH_SQLITE_GEN_MAX) return;
121
+ s->gen++;
122
+ if (t->tail != 0) t->at[t->tail].next = i;
123
+ else t->head = i;
124
+ t->tail = i;
125
+ }
126
+
127
+ /* ---- Connections -------------------------------------------------------- */
128
+
129
+ #define NISH_SQLITE_OPEN_FLAGS \
130
+ (SQLITE_OPEN_READONLY | SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | \
131
+ SQLITE_OPEN_URI | SQLITE_OPEN_MEMORY | SQLITE_OPEN_NOFOLLOW)
132
+
133
+ /* A handle, or the negated extended code with its message kept for
134
+ * `nishsqlite_open_errmsg`. The flags are SQLite's, less those this build
135
+ * has no use for, and must hold READONLY, READWRITE or READWRITE|CREATE:
136
+ * anything else is SQLITE_MISUSE, where SQLite leaves it undefined. */
137
+ int32_t nishsqlite_open(const char *path, int32_t flags) {
138
+ int32_t mode = flags & 7;
139
+ if ((flags & ~NISH_SQLITE_OPEN_FLAGS) != 0 || (mode != 1 && mode != 2 && mode != 6)) {
140
+ strcpy(nishsqlite_open_message, sqlite3_errstr(SQLITE_MISUSE));
141
+ return -SQLITE_MISUSE;
142
+ }
143
+ sqlite3 *db = NULL;
144
+ int rc = sqlite3_open_v2(path, &db, flags | SQLITE_OPEN_EXRESCODE, NULL);
145
+ if (rc == SQLITE_OK) {
146
+ int32_t h = slot_take(&nishsqlite_dbs, db, 0);
147
+ if (h != 0) return h;
148
+ rc = SQLITE_NOMEM;
149
+ }
150
+ const char *message = db && rc != SQLITE_NOMEM ? sqlite3_errmsg(db) : sqlite3_errstr(rc);
151
+ strncpy(nishsqlite_open_message, message, sizeof nishsqlite_open_message - 1);
152
+ sqlite3_close_v2(db);
153
+ return -rc;
154
+ }
155
+
156
+ /* The message of the last `nishsqlite_open` that failed on this thread. */
157
+ const char *nishsqlite_open_errmsg(void) { return nishsqlite_open_message; }
158
+
159
+ /* Finalizes every statement of the connection, frees their handles, then
160
+ * closes it. close_v2 rather than close, so a connection something else still
161
+ * holds (none can, today) is closed when that ends instead of staying open.
162
+ * The handle is freed only once the close succeeds, so a close that fails
163
+ * leaves the connection usable and its message readable. */
164
+ int32_t nishsqlite_close(int32_t h) {
165
+ sqlite3 *db = db_of(h);
166
+ if (db == NULL) return SQLITE_MISUSE;
167
+ nishsqlite_table *t = &nishsqlite_stmts;
168
+ for (int32_t i = 1; i < t->len; i++) {
169
+ if (t->at[i].p != NULL && t->at[i].owner == h) {
170
+ sqlite3_finalize((sqlite3_stmt *)t->at[i].p);
171
+ slot_give(t, (t->at[i].gen << 16) | i);
172
+ }
173
+ }
174
+ int rc = sqlite3_close_v2(db);
175
+ if (rc == SQLITE_OK) slot_give(&nishsqlite_dbs, h);
176
+ return rc;
177
+ }
178
+
179
+ int32_t nishsqlite_exec(int32_t h, const char *sql) {
180
+ sqlite3 *db = db_of(h);
181
+ return db ? sqlite3_exec(db, sql, NULL, NULL, NULL) : SQLITE_MISUSE;
182
+ }
183
+
184
+ /* The connection's message for its last failure, or SQLITE_MISUSE's own for
185
+ * a handle that names no connection. */
186
+ const char *nishsqlite_errmsg(int32_t h) {
187
+ sqlite3 *db = db_of(h);
188
+ return db ? sqlite3_errmsg(db) : sqlite3_errstr(SQLITE_MISUSE);
189
+ }
190
+
191
+ int64_t nishsqlite_last_insert_rowid(int32_t h) {
192
+ sqlite3 *db = db_of(h);
193
+ return db ? sqlite3_last_insert_rowid(db) : 0;
194
+ }
195
+
196
+ int64_t nishsqlite_changes(int32_t h) {
197
+ sqlite3 *db = db_of(h);
198
+ return db ? sqlite3_changes64(db) : 0;
199
+ }
200
+
201
+ /* ---- Statements --------------------------------------------------------- */
202
+
203
+ /* A statement handle for the first statement of `sql`, or the negated code.
204
+ * Text with no statement in it, only space or comments, is SQLITE_MISUSE:
205
+ * SQLite answers OK and no statement, which leaves nothing to hand back. */
206
+ int32_t nishsqlite_prepare(int32_t h, const char *sql) {
207
+ sqlite3 *db = db_of(h);
208
+ if (db == NULL) return -SQLITE_MISUSE;
209
+ sqlite3_stmt *st = NULL;
210
+ int rc = sqlite3_prepare_v3(db, sql, -1, SQLITE_PREPARE_PERSISTENT, &st, NULL);
211
+ if (rc != SQLITE_OK) return -rc;
212
+ if (st == NULL) return -SQLITE_MISUSE;
213
+ int32_t s = slot_take(&nishsqlite_stmts, st, h);
214
+ if (s != 0) return s;
215
+ sqlite3_finalize(st);
216
+ return -SQLITE_NOMEM;
217
+ }
218
+
219
+ /* The message of the statement's connection, as `nishsqlite_errmsg`. */
220
+ const char *nishsqlite_stmt_errmsg(int32_t h) {
221
+ sqlite3_stmt *st = stmt_of(h);
222
+ return st ? sqlite3_errmsg(sqlite3_db_handle(st)) : sqlite3_errstr(SQLITE_MISUSE);
223
+ }
224
+
225
+ int32_t nishsqlite_finalize(int32_t h) {
226
+ sqlite3_stmt *st = stmt_of(h);
227
+ if (st == NULL) return SQLITE_MISUSE;
228
+ sqlite3_finalize(st);
229
+ slot_give(&nishsqlite_stmts, h);
230
+ return SQLITE_OK;
231
+ }
232
+
233
+ int32_t nishsqlite_step(int32_t h) {
234
+ sqlite3_stmt *st = stmt_of(h);
235
+ return st ? sqlite3_step(st) : SQLITE_MISUSE;
236
+ }
237
+
238
+ /* SQLite's reset answers the last step's failure again; the program has seen
239
+ * that from `step`, so this answers only whether the handle is good. */
240
+ int32_t nishsqlite_reset(int32_t h) {
241
+ sqlite3_stmt *st = stmt_of(h);
242
+ if (st == NULL) return SQLITE_MISUSE;
243
+ sqlite3_reset(st);
244
+ return SQLITE_OK;
245
+ }
246
+
247
+ int32_t nishsqlite_clear_bindings(int32_t h) {
248
+ sqlite3_stmt *st = stmt_of(h);
249
+ return st ? sqlite3_clear_bindings(st) : SQLITE_MISUSE;
250
+ }
251
+
252
+ int32_t nishsqlite_bind_i64(int32_t h, int32_t i, int64_t v) {
253
+ sqlite3_stmt *st = stmt_of(h);
254
+ return st ? sqlite3_bind_int64(st, i, v) : SQLITE_MISUSE;
255
+ }
256
+
257
+ int32_t nishsqlite_bind_f64(int32_t h, int32_t i, double v) {
258
+ sqlite3_stmt *st = stmt_of(h);
259
+ return st ? sqlite3_bind_double(st, i, v) : SQLITE_MISUSE;
260
+ }
261
+
262
+ int32_t nishsqlite_bind_null(int32_t h, int32_t i) {
263
+ sqlite3_stmt *st = stmt_of(h);
264
+ return st ? sqlite3_bind_null(st, i) : SQLITE_MISUSE;
265
+ }
266
+
267
+ int32_t nishsqlite_bind_text(int32_t h, int32_t i, const char *text) {
268
+ sqlite3_stmt *st = stmt_of(h);
269
+ return st ? sqlite3_bind_text(st, i, text, -1, SQLITE_TRANSIENT) : SQLITE_MISUSE;
270
+ }
271
+
272
+ /* Binds `buf[off, off + len)`, `n` the buffer's length: as text when `blob` is
273
+ * 0, as a blob otherwise. A window outside the buffer is SQLITE_MISUSE. A
274
+ * window of no bytes binds the empty value, never NULL, which is what SQLite
275
+ * would bind for the pointer of an empty array. */
276
+ int32_t nishsqlite_bind_bytes(int32_t h, int32_t i, const uint8_t *buf, uint64_t n, int32_t off,
277
+ int32_t len, int32_t blob) {
278
+ sqlite3_stmt *st = stmt_of(h);
279
+ if (st == NULL || off < 0 || len < 0 || (uint64_t)off + (uint64_t)len > n) return SQLITE_MISUSE;
280
+ const void *p = len == 0 ? (const void *)"" : (const void *)(buf + off);
281
+ return blob ? sqlite3_bind_blob(st, i, p, len, SQLITE_TRANSIENT)
282
+ : sqlite3_bind_text(st, i, (const char *)p, len, SQLITE_TRANSIENT);
283
+ }
284
+
285
+ /* ---- Columns ------------------------------------------------------------ */
286
+
287
+ /* These answer what SQLite does for a column that is not there, 0 and
288
+ * SQLITE_NULL, for a handle that names no statement too: a read cannot fail,
289
+ * and the step before it already answered whether the statement is good. A
290
+ * column that is not there, or any column when no row is current (before the
291
+ * first step, or after the last), is answered here, before SQLite, which would
292
+ * otherwise record SQLITE_RANGE as the connection's last error. */
293
+
294
+ /* The statement `h` names, when its current row has a column `c`; NULL
295
+ * otherwise. sqlite3_data_count is 0 when no row is current. */
296
+ static inline sqlite3_stmt *column_of(int32_t h, int32_t c) {
297
+ sqlite3_stmt *st = stmt_of(h);
298
+ return st && c >= 0 && c < sqlite3_data_count(st) ? st : NULL;
299
+ }
300
+
301
+ int32_t nishsqlite_column_count(int32_t h) {
302
+ sqlite3_stmt *st = stmt_of(h);
303
+ return st ? sqlite3_column_count(st) : 0;
304
+ }
305
+
306
+ int32_t nishsqlite_column_type(int32_t h, int32_t c) {
307
+ sqlite3_stmt *st = column_of(h, c);
308
+ return st ? sqlite3_column_type(st, c) : SQLITE_NULL;
309
+ }
310
+
311
+ int64_t nishsqlite_column_i64(int32_t h, int32_t c) {
312
+ sqlite3_stmt *st = column_of(h, c);
313
+ return st ? sqlite3_column_int64(st, c) : 0;
314
+ }
315
+
316
+ double nishsqlite_column_f64(int32_t h, int32_t c) {
317
+ sqlite3_stmt *st = column_of(h, c);
318
+ return st ? sqlite3_column_double(st, c) : 0.0;
319
+ }
320
+
321
+ /* The column's length in bytes as `nishsqlite_column_into` would copy it:
322
+ * a blob's bytes, or anything else as text. */
323
+ int32_t nishsqlite_column_bytes(int32_t h, int32_t c) {
324
+ sqlite3_stmt *st = column_of(h, c);
325
+ if (st == NULL) return 0;
326
+ if (sqlite3_column_type(st, c) != SQLITE_BLOB) sqlite3_column_text(st, c);
327
+ return sqlite3_column_bytes(st, c);
328
+ }
329
+
330
+ /* The column as text, for a `string` result; NULL for SQL NULL. */
331
+ const char *nishsqlite_column_text(int32_t h, int32_t c) {
332
+ sqlite3_stmt *st = column_of(h, c);
333
+ return st ? (const char *)sqlite3_column_text(st, c) : NULL;
334
+ }
335
+
336
+ /* Copies column `c`, a blob's bytes or anything else as text, into `buf` at
337
+ * `at`, `n` the buffer's length, and answers the column's length. It copies
338
+ * only when all of it fits, so a length past `n - at` says how much room the
339
+ * read needs and nothing was written. SQLITE_MISUSE for a bad handle or an
340
+ * `at` outside `0..n`, SQLITE_RANGE for a column that is not there, and
341
+ * SQLITE_NOMEM when SQLite cannot convert a value to text, all negated. Only
342
+ * a NULL or a blob has no pointer and is still read: an empty blob has none.
343
+ * A column of the statement read when no row is current answers 0 and writes
344
+ * nothing, as a NULL does, without asking SQLite. */
345
+ int32_t nishsqlite_column_into(int32_t h, int32_t c, uint8_t *buf, uint64_t n, int32_t at) {
346
+ sqlite3_stmt *st = stmt_of(h);
347
+ if (st == NULL || at < 0 || (uint64_t)at > n) return -SQLITE_MISUSE;
348
+ /* With a row current sqlite3_data_count is the column count, so the row's
349
+ * path asks SQLite once where it would ask twice. */
350
+ int32_t cols = sqlite3_data_count(st);
351
+ if (cols == 0) return c < 0 || c >= sqlite3_column_count(st) ? -SQLITE_RANGE : 0;
352
+ if (c < 0 || c >= cols) return -SQLITE_RANGE;
353
+ int type = sqlite3_column_type(st, c);
354
+ const void *p = type == SQLITE_BLOB ? sqlite3_column_blob(st, c) : (const void *)sqlite3_column_text(st, c);
355
+ if (p == NULL && type != SQLITE_NULL && type != SQLITE_BLOB) return -SQLITE_NOMEM;
356
+ int32_t len = sqlite3_column_bytes(st, c);
357
+ if (p != NULL && (uint64_t)len <= n - (uint64_t)at) memcpy(buf + at, p, (size_t)len);
358
+ return len;
359
+ }