mirror of
https://github.com/sqlite/sqlite.git
synced 2026-10-23 21:49:02 +03:00
Latest upstream ext/wasm/libcmpp.c, primarily to make it filcc-legal (only the final chunk in the diff - the rest is minor changes accumulated since the last update).
FossilOrigin-Name: 06f3bbc5bddc2e763042f8b487a3deedf47c54b7fa785ba6fd6abd524b4cbe3a
This commit is contained in:
@@ -15,13 +15,13 @@
|
||||
|
||||
./c-pp -I. -I./src -Dsrcdir=./src -Dsed=/usr/bin/sed -o libcmpp.h ./tool/libcmpp.c-pp.h -o libcmpp.c ./tool/libcmpp.c-pp.c
|
||||
|
||||
with libcmpp 2.0.x c02f3e3e2d3f3573a9a33c1474c2e52fc48e52c70730404a90d0ae51517e7d37 @ 2026-03-08 14:50:35.123 UTC
|
||||
with libcmpp 2.0.x a53a63923506aba565e91571c0f6bdb678e7dcc05dc9f7e281a17e68bf95aa46 @ 2026-07-21 10:38:56.344 UTC
|
||||
*/
|
||||
#define CMPP_PACKAGE_NAME "libcmpp"
|
||||
#define CMPP_LIB_VERSION "2.0.x"
|
||||
#define CMPP_LIB_VERSION_HASH "c02f3e3e2d3f3573a9a33c1474c2e52fc48e52c70730404a90d0ae51517e7d37"
|
||||
#define CMPP_LIB_VERSION_TIMESTAMP "2026-03-08 14:50:35.123 UTC"
|
||||
#define CMPP_LIB_CONFIG_TIMESTAMP "2026-03-08 15:32 GMT"
|
||||
#define CMPP_LIB_VERSION_HASH "a53a63923506aba565e91571c0f6bdb678e7dcc05dc9f7e281a17e68bf95aa46"
|
||||
#define CMPP_LIB_VERSION_TIMESTAMP "2026-07-21 10:38:56.344 UTC"
|
||||
#define CMPP_LIB_CONFIG_TIMESTAMP "2026-07-21 10:39 GMT"
|
||||
#define CMPP_VERSION CMPP_LIB_VERSION " " CMPP_LIB_VERSION_HASH " @ " CMPP_LIB_VERSION_TIMESTAMP
|
||||
#define CMPP_PLATFORM_EXT_DLL ".so"
|
||||
#define CMPP_MODULE_PATH ".:/usr/local/lib/cmpp"
|
||||
@@ -54,22 +54,16 @@
|
||||
** at build-time.
|
||||
**
|
||||
** This API is presented as a library but was evolved from a
|
||||
** monolithic app. Thus is library interface is likely still missing
|
||||
** monolithic app. Thus the library interface is likely still missing
|
||||
** some pieces needed to make it more readily usable as a library.
|
||||
**
|
||||
** Author(s):
|
||||
**
|
||||
** - Stephan Beal <https://wanderinghorse.net/home/stephan/>
|
||||
**
|
||||
** Canonical homes:
|
||||
** Canonical home:
|
||||
**
|
||||
** - https://fossil.wanderinghorse.net/r/c-pp
|
||||
** - https://sqlite.org/src/file/ext/wasm/c-pp-lite.c
|
||||
**
|
||||
** With the former hosting this app's SCM and the latter being the
|
||||
** original deployment of c-pp.c, from which this library
|
||||
** evolved. SQLite uses a "lite" version of c-pp, whereas _this_ copy
|
||||
** is its much-heavier-weight fork.
|
||||
** - <https://fossil.wanderinghorse.net/r/c-pp>
|
||||
*/
|
||||
|
||||
#if defined(CMPP_HAVE_AUTOCONFIG_H)
|
||||
@@ -404,8 +398,9 @@ typedef struct cmpp_ctor_cfg cmpp_ctor_cfg;
|
||||
it failed). In either case, the caller must eventually pass *pp to
|
||||
cmpp_dtor() to free it.
|
||||
|
||||
If the library is built with the symbol CMPP_CTOR_INSTANCE_INIT
|
||||
defined, it must refer to a function with this signature:
|
||||
If the library is built with the preprocessor symbol
|
||||
CMPP_CTOR_INSTANCE_INIT defined, it must refer to a function with
|
||||
this signature:
|
||||
|
||||
int CMPP_CTOR_INSTANCE_INIT(cmpp *);
|
||||
|
||||
@@ -576,13 +571,9 @@ CMPP_EXPORT int cmpp_undef(cmpp *pp, const char * zKey,
|
||||
unsigned int *nRemoved);
|
||||
|
||||
/**
|
||||
This works similarly to cmpp_define_v2() except that:
|
||||
|
||||
- It does not permit its zKey argument to contain the value
|
||||
part like that function does.
|
||||
|
||||
- The new define "shadows", rather than overwrites, an existing
|
||||
define with the same name.
|
||||
This works similarly to cmpp_define_v2() except that the new define
|
||||
"shadows", rather than overwrites, an existing define with the same
|
||||
name.
|
||||
|
||||
All APIs which look up define keys will get the value of the shadow
|
||||
define. The shadow can be uninstalled with cmpp_define_unshadow(),
|
||||
@@ -590,9 +581,9 @@ CMPP_EXPORT int cmpp_undef(cmpp *pp, const char * zKey,
|
||||
should be called one time for each call to this one, passing the
|
||||
same key to each call. A given key may be shadowed any number of
|
||||
times by this routine. Each one saves the internal ID of the shadow
|
||||
into *pId (and pId must not be NULL). That value must be passed to
|
||||
into *pId (which must not be NULL). That value must be passed to
|
||||
cmpp_define_unshadow() to ensure that the "shadow stack" stays
|
||||
balanced in the face of certain error-handling paths.
|
||||
balanced.
|
||||
|
||||
cmpp_undef() will _not_ undefine an entry added through this
|
||||
interface.
|
||||
@@ -610,9 +601,9 @@ CMPP_EXPORT int cmpp_define_shadow(cmpp *pp, char const *zKey,
|
||||
int64_t * pId);
|
||||
|
||||
/**
|
||||
Removes the most shadow define matching the zKey and id values
|
||||
which where previously passed to cmpp_define_shadow(). It is not
|
||||
an error if no match is found, in which case this function has no
|
||||
Removes the shadow define matching the zKey and id values which
|
||||
where previously passed to cmpp_define_shadow(). It is not an
|
||||
error if no match is found, in which case this function has no
|
||||
visible side-effects.
|
||||
|
||||
Unlike cmpp_undef(), zKey is matched precisely, not against a glob.
|
||||
@@ -930,8 +921,8 @@ CMPP_EXPORT bool cmpp_is_safemode(cmpp const * pp);
|
||||
Starts a new SAVEPOINT in the database. Returns non-0, and updates
|
||||
pp's persistent error state, on failure.
|
||||
|
||||
If this returns 0, the caller is obligated to later call either
|
||||
cmpp_sp_commit() or cmpp_sp_rollback() later.
|
||||
If this returns 0, the caller is obligated to later pass pp to one
|
||||
of cmpp_sp_commit() or cmpp_sp_rollback().
|
||||
*/
|
||||
CMPP_EXPORT int cmpp_sp_begin(cmpp *pp);
|
||||
|
||||
@@ -1033,7 +1024,7 @@ CMPP_EXPORT int cmpp_stream(cmpp_input_f inF, void * inState,
|
||||
and *nOut to the number of bytes read (which will be fewer than are
|
||||
allocated). It guarantees that on success it NUL-terminates the
|
||||
buffer at one byte after the returned size, with one exception: if
|
||||
the string has no input, both *pOut and *nOut will be set to 0.
|
||||
the stream has no input, both *pOut and *nOut will be set to 0.
|
||||
|
||||
On error it returns whatever code xIn() returns.
|
||||
*/
|
||||
@@ -1173,7 +1164,7 @@ CMPP_EXPORT void cmpp_outputer_cleanup_f_FILE(cmpp_outputer *self);
|
||||
/**
|
||||
Sets pp's current directive delimiter to a copy of the
|
||||
NUL-terminated zDelim. The delimiter is the sequence which starts
|
||||
line and distinguishes cmpp directives from other input, in the
|
||||
lines and distinguishes cmpp directives from other input, in the
|
||||
same way that C preprocessors use '#' as a delimiter.
|
||||
|
||||
If zDelim is NULL then the default delimiter is used. The default
|
||||
@@ -1193,9 +1184,9 @@ CMPP_EXPORT void cmpp_outputer_cleanup_f_FILE(cmpp_outputer *self);
|
||||
the delimiter.
|
||||
|
||||
Returns 0 on success. Returns non-0 if called when the delimiter
|
||||
stack is empty, if it cannot copy the string or zDelim is deemed
|
||||
stack is empty, if it cannot copy the string, or zDelim is deemed
|
||||
unsuitable for use as a delimiter. Calling this when the stack is
|
||||
empty represents a serious API misuse (indicating that
|
||||
empty represents a serious API misuse (possibly indicating that
|
||||
cmpp_delimiter_pop() was used out of scope) and will trigger an
|
||||
assert() in debug builds. Except for that last case, errors from
|
||||
this function are recoverable (see cmpp_err_set()).
|
||||
@@ -1209,8 +1200,9 @@ CMPP_EXPORT int cmpp_delimiter_set(cmpp *pp, char const *zDelim);
|
||||
|
||||
If, by some odd usage constellation, this is called after an
|
||||
allocation of the delimiter stack has failed, this will set *zDelim
|
||||
to the compile-time-default delimiter. That "cannot happen" in normal use because such a failure
|
||||
would have been reacted to and this would not be called.
|
||||
to the compile-time-default delimiter. That "cannot happen" in
|
||||
normal use because such a failure would have been reacted to and
|
||||
this would not be called.
|
||||
*/
|
||||
CMPP_EXPORT void cmpp_delimiter_get(cmpp const *pp, char const **zDelim);
|
||||
|
||||
@@ -1244,8 +1236,8 @@ CMPP_EXPORT bool cmpp_chomp(unsigned char * z, cmpp_size_t * n);
|
||||
|
||||
/**
|
||||
A basic memory buffer class. This is primarily used with
|
||||
cmpp_outputer_b to capture arbitrary output for later use.
|
||||
It's also used for incrementally creating dynamic strings.
|
||||
cmpp_outputer_b to capture arbitrary output for later use and for
|
||||
incrementally creating dynamic strings.
|
||||
|
||||
TODO: add the heuristic that an nAlloc of 0 with a non-NULL z
|
||||
refers to externally-owned memory. This would change the
|
||||
@@ -1262,6 +1254,9 @@ struct cmpp_b {
|
||||
|
||||
If this pointer is taken away from this object then it must
|
||||
eventually be passed to cmpp_mfree().
|
||||
|
||||
This class's APIs strive to keep valid buffers NUL-terminated at
|
||||
byte this->z[this->n].
|
||||
*/
|
||||
unsigned char * z;
|
||||
/**
|
||||
@@ -1330,8 +1325,9 @@ CMPP_EXPORT void cmpp_b_swap(cmpp_b * l, cmpp_b * r);
|
||||
CMPP_EXPORT int cmpp_b_reserve(cmpp_b *s, cmpp_size_t n);
|
||||
|
||||
/**
|
||||
Works just like cmpp_b_reserve() but on allocation error it
|
||||
updates pp's error state.
|
||||
Works just like cmpp_b_reserve() but on allocation error it updates
|
||||
pp's error state. If called when pp has error state, that code is
|
||||
returned and this function has no side-effects.
|
||||
*/
|
||||
CMPP_EXPORT int cmpp_b_reserve3(cmpp * pp, cmpp_b * os, cmpp_size_t n);
|
||||
|
||||
@@ -1346,8 +1342,9 @@ CMPP_EXPORT int cmpp_b_append(cmpp_b * os, void const *src,
|
||||
cmpp_size_t n);
|
||||
|
||||
/**
|
||||
Works just like cmpp_b_append() but on allocation error it
|
||||
updates pp's error state.
|
||||
Works just like cmpp_b_append() but on allocation error it updates
|
||||
pp's error state. If called when pp has error state, that code is
|
||||
returned and this function has no side-effects.
|
||||
*/
|
||||
CMPP_EXPORT int cmpp_b_append4(cmpp * pp,
|
||||
cmpp_b * os,
|
||||
@@ -1448,10 +1445,10 @@ enum cmpp_tt {
|
||||
|
||||
- GroupParen, GroupBrace, GroupSquiggly: (), [], and {}
|
||||
|
||||
- All which start with D_ are directives. D_Line is a transitional
|
||||
state between "unparsed" and another D_... value.
|
||||
- RawLine: the token contains the raw, unparsed arguments line for
|
||||
a directive.
|
||||
*/
|
||||
#define cmpp_tt_map(E) \
|
||||
#define cmpp_tt_map(E) \
|
||||
E(None, 0) \
|
||||
E(RawLine, 0) \
|
||||
E(Unknown, 0) \
|
||||
@@ -1496,7 +1493,7 @@ typedef enum cmpp_tt cmpp_tt;
|
||||
|
||||
/**
|
||||
For all of the cmpp_tt enum entries, returns a string form of the
|
||||
enum entry name, e.g. "cmpp_TT_D_If". Returns NULL for any other
|
||||
enum entry name, e.g. "cmpp_TT_String". Returns NULL for any other
|
||||
values
|
||||
*/
|
||||
CMPP_EXPORT char const * cmpp_tt_cstr(int tt);
|
||||
@@ -1624,14 +1621,13 @@ enum cmpp_d_e {
|
||||
|
||||
/**
|
||||
Indicates that the direction should not be available if the cmpp
|
||||
instance is configured with any of the cmpp_ctor_F_SAFEMODE flags.
|
||||
All directives when do any of the following are obligated to
|
||||
set this flag:
|
||||
instance is configured with the cmpp_ctor_F_SAFEMODE flag. All
|
||||
directives which do any of the following are obligated to set
|
||||
this flag:
|
||||
|
||||
- Filesystem or network access.
|
||||
- Invoking external processes.
|
||||
|
||||
Or anything else which might be deamed "security-relevant".
|
||||
- Anything else which might be deamed "security-relevant".
|
||||
|
||||
When registering a directive which has both opener and closer
|
||||
implementations, it is sufficient to set this only on the opener.
|
||||
@@ -1653,7 +1649,7 @@ enum cmpp_d_e {
|
||||
cmpp_d_F_CALL_ONLY = 0x08,
|
||||
/**
|
||||
Indicates that the directive is incapable of working in a [call]
|
||||
context and an error should be trigger if it is. _Most_
|
||||
context and an error should be triggered if it is. _Most_
|
||||
directives which have a closing directive should have this
|
||||
flag. The exceptions are directives which only conditionally use
|
||||
a closing directive, like #query.
|
||||
@@ -1701,15 +1697,10 @@ typedef void (*cmpp_finalizer_f)(void *);
|
||||
|
||||
/**
|
||||
State specific to concrete cmpp_d implementations.
|
||||
|
||||
TODO: move this, except for the state pointer, out of cmpp_d
|
||||
so that directives cannot invoke these callbacks directly. Getting
|
||||
that to work requires moving the builtin directives into the
|
||||
dynamic directives list.
|
||||
*/
|
||||
struct cmpp_d_impl {
|
||||
/**
|
||||
Callback func. If any API other othan cmpp_dx_process() invokes
|
||||
Callback func. If any API other than cmpp_dx_process() invokes
|
||||
this, behavior is undefined.
|
||||
*/
|
||||
cmpp_dx_f callback;
|
||||
@@ -2525,7 +2516,7 @@ CMPP_EXPORT char const * cmpp_dx_delim(cmpp_dx const *dx);
|
||||
This transfers ownership of the buffer to the caller, who is
|
||||
obligated to eventually do ONE of the following:
|
||||
|
||||
- Pass it to cmpp_b_return() with the same dx argument.
|
||||
- Pass it to cmpp_b_return() with the same pp argument.
|
||||
|
||||
- Pass it to cmpp_b_clear() then cmpp_mfree().
|
||||
|
||||
@@ -2538,19 +2529,19 @@ CMPP_EXPORT char const * cmpp_dx_delim(cmpp_dx const *dx);
|
||||
about the buffer usage. e.g. argument-conversion buffers are
|
||||
normally small but block content buffers can be arbitrarily large.
|
||||
*/
|
||||
CMPP_EXPORT cmpp_b * cmpp_b_borrow(cmpp *dx);
|
||||
CMPP_EXPORT cmpp_b * cmpp_b_borrow(cmpp *pp);
|
||||
|
||||
/**
|
||||
Returns a buffer borrowed from cmpp_b_borrow(), transferring
|
||||
ownership back to pp. Passing a non-NULL b which was not returned
|
||||
by cmpp_b_borrow() invoked undefined behavior (possibly delayed
|
||||
by cmpp_b_borrow() invokes undefined behavior (possibly delayed
|
||||
until the list is cleaned up). To simplify usage, b may be NULL.
|
||||
|
||||
After calling this, b must be considered "freed" - it must not be
|
||||
used again. This function is free (as it were) to immediately free
|
||||
the object's memory instead of recycling it.
|
||||
*/
|
||||
CMPP_EXPORT void cmpp_b_return(cmpp *dx, cmpp_b *b);
|
||||
CMPP_EXPORT void cmpp_b_return(cmpp *pp, cmpp_b *b);
|
||||
|
||||
/**
|
||||
If NUL-terminated z matches one of the strings listed below, its
|
||||
@@ -4520,6 +4511,7 @@ struct cmpp_args_pimpl {
|
||||
We need(?) a (cmpp*) here for finalization/recycling purposes.
|
||||
*/
|
||||
cmpp *pp;
|
||||
/** True if these are the arguments for [call...] syntax. */
|
||||
bool isCall;
|
||||
/**
|
||||
Next entry in the free-list.
|
||||
@@ -4596,9 +4588,9 @@ struct cmpp_dx_pimpl {
|
||||
Record IDs for/from cmpp_[un]define_shadow().
|
||||
*/
|
||||
struct {
|
||||
/** ID for __FILE__. */
|
||||
/** Shadow-define rowid for __FILE__. */
|
||||
int64_t sidFile;
|
||||
/** Rowid for #include path entry. */
|
||||
/** Shadow-define rowid for #include path entry. */
|
||||
int64_t ridInclPath;
|
||||
} shadow;
|
||||
|
||||
@@ -4614,6 +4606,7 @@ struct cmpp_dx_pimpl {
|
||||
bool nextIsCall;
|
||||
} flags;
|
||||
};
|
||||
|
||||
/**
|
||||
Initializes or resets a. Returns non-0 on OOM.
|
||||
*/
|
||||
@@ -4737,7 +4730,7 @@ CMPP_PRIVATE int CmppKvp_parse(cmpp *pp, CmppKvp * p,
|
||||
Stack of POD values. Intended for use with cmpp at-token and
|
||||
undefined key policies.
|
||||
*/
|
||||
#define cmpp__PodList_decl(ST,ET) \
|
||||
#define cmpp__PodList_decl(ST,ET) \
|
||||
struct ST { \
|
||||
/* current stack index */ \
|
||||
cmpp_size_t n; \
|
||||
@@ -4751,7 +4744,7 @@ CMPP_PRIVATE int CmppKvp_parse(cmpp *pp, CmppKvp * p,
|
||||
void ST ## _pop(ST *s); \
|
||||
int ST ## _reserve(cmpp *, ST *, cmpp_size_t min)
|
||||
|
||||
#define cmpp__PodList_impl(ST,ET) \
|
||||
#define cmpp__PodList_impl(ST,ET) \
|
||||
void ST ## _wipe(ST * const s, ET v){ \
|
||||
if( s->na ) memset(s->stack, (int)v, sizeof(ET)*s->na); \
|
||||
s->n = 0; \
|
||||
@@ -4933,11 +4926,13 @@ struct cmpp_pimpl {
|
||||
"(SELECT v FROM " CMPP__DB_MAIN_NAME ".vdef WHERE k=?" #N \
|
||||
" ORDER BY source LIMIT 1)"
|
||||
|
||||
/** Name of library-generated savepoints. */
|
||||
#define CMPP__SAVEPOINT_NAME "_cmpp_"
|
||||
|
||||
/**
|
||||
One entry for each distinct query used by cmpp: E(X,SQL), where
|
||||
X is the member's name and SQL is its SQL.
|
||||
*/
|
||||
#define CMPP_SAVEPOINT_NAME "_cmpp_"
|
||||
#define CmppStmt_map(E) \
|
||||
E(sdefIns, \
|
||||
"INSERT INTO " \
|
||||
@@ -5019,16 +5014,16 @@ struct cmpp_pimpl {
|
||||
"ATTACH ?1 AS ?2") \
|
||||
E(dbDetach, \
|
||||
"DETACH ?1") \
|
||||
E(spBegin, "SAVEPOINT " CMPP_SAVEPOINT_NAME) \
|
||||
E(spBegin, "SAVEPOINT " CMPP__SAVEPOINT_NAME) \
|
||||
E(spRollback, \
|
||||
"ROLLBACK TO SAVEPOINT " CMPP_SAVEPOINT_NAME) \
|
||||
"ROLLBACK TO SAVEPOINT " CMPP__SAVEPOINT_NAME) \
|
||||
E(spRelease, \
|
||||
"RELEASE SAVEPOINT " CMPP_SAVEPOINT_NAME) \
|
||||
"RELEASE SAVEPOINT " CMPP__SAVEPOINT_NAME) \
|
||||
E(insTtype, \
|
||||
"INSERT INTO " CMPP__DB_MAIN_NAME ".ttype" \
|
||||
"(t,n,s) VALUES(?1,?2,?3)") \
|
||||
E(selPathSearch, \
|
||||
/* sqlite.org/forum/forumpost/840c98a8e87c2207 */ \
|
||||
/* sqlite.org/forum/forumpost/840c98a8e87c2207 */ \
|
||||
"WITH path(basename, sep, ext, path) AS (\n" \
|
||||
" select\n" \
|
||||
" ?1 basename,\n" \
|
||||
@@ -5067,8 +5062,7 @@ struct cmpp_pimpl {
|
||||
"where r<>'' and cmpp_file_exists(fn)\n" \
|
||||
"order by i\n" \
|
||||
"limit 1;")
|
||||
|
||||
/* trivia: selPathSearch (^^^) was generated using
|
||||
/* trivia: selPathSearch (^^^) was initially generated using
|
||||
cmpp's #c-code directive. */
|
||||
|
||||
#define E(N,S) sqlite3_stmt * N;
|
||||
@@ -5200,7 +5194,7 @@ struct cmpp_pimpl {
|
||||
enum cmpp_b_list_e bufSort;
|
||||
/**
|
||||
Head of the free-list.
|
||||
*/
|
||||
*/
|
||||
cmpp_args_pimpl * argPimpl;
|
||||
} recycler;
|
||||
};
|
||||
@@ -5697,9 +5691,9 @@ char const * cmpp__unpol_name(cmpp *pp, cmpp_unpol_e p);
|
||||
cmpp_b bMine = cmpp_b_empty;
|
||||
cmpp_outputer oOld = {0};
|
||||
oMine.state = &bMine;
|
||||
cmpp_outputer_swap(pp, &myOut, &oOld);
|
||||
cmpp__outputer_swap(pp, &oMine, &oOld);
|
||||
...do some work then ALWAYS do...
|
||||
cmpp_outputer_swap(pp, &oOld, &oMine);
|
||||
cmpp__outputer_swap(pp, &oOld, &oMine);
|
||||
```
|
||||
|
||||
Because this involves bitwise copying, care must be taken with
|
||||
@@ -6942,7 +6936,6 @@ int cmpp__bind_textv(cmpp*pp, sqlite3_stmt *pStmt, int col,
|
||||
int n = 0;
|
||||
char * z;
|
||||
va_list va;
|
||||
if( !str ) return ppCode;
|
||||
va_start(va,zFmt);
|
||||
sqlite3_str_vappendf(str, zFmt, va);
|
||||
va_end(va);
|
||||
@@ -8208,7 +8201,7 @@ CMPP__EXPORT(int, cmpp_dx_next)(cmpp_dx * const dx, bool * pGotOne){
|
||||
assert( !pimpl->args.pimpl->argOut.n );
|
||||
assert( !pimpl->args.pimpl->argli.n );
|
||||
assert( dx->args.z );
|
||||
if( //1 || //pleases valgrind. Well, it did at one point.
|
||||
if( //pleases valgrind. Well, it did at one point.
|
||||
!cmpp_dx_is_eliding(dx) || 0!=(cmpp_d_F_FLOW_CONTROL & dx->d->flags) ){
|
||||
if( cmpp_d_F_ARGS_LIST & dx->d->flags ){
|
||||
cmpp_dx_args_parse(dx, &pimpl->args);
|
||||
@@ -8993,7 +8986,7 @@ int cmpp_process_file(cmpp *pp, const char * zName){
|
||||
}
|
||||
|
||||
CMPP__EXPORT(int, cmpp_process_stream)(cmpp *pp, const char * zName,
|
||||
cmpp_input_f src, void * srcState){
|
||||
cmpp_input_f src, void * srcState){
|
||||
if( 0==ppCode ){
|
||||
cmpp_b * const os = cmpp_b_borrow(pp);
|
||||
int const rc = os
|
||||
@@ -10233,8 +10226,9 @@ const cmpp_outputer cmpp_outputer_obuf = {
|
||||
*/
|
||||
static int cmpp__prepare(cmpp *pp, sqlite3_stmt **pStmt,
|
||||
const char * zSql, ...){
|
||||
/* We need for pp->pimpl->stmt.sp* to work regardless of pending errors so
|
||||
that we can, when appropriate, create the rollback statements. */
|
||||
/* We need for pp->pimpl->stmt.sp* to work regardless of pending
|
||||
errors so that we can, when appropriate, create the rollback
|
||||
statements. Thus we don't check ppCode before starting. */
|
||||
sqlite3_str * str = sqlite3_str_new(pp->pimpl->db.dbh);
|
||||
char * z = 0;
|
||||
int n = 0;
|
||||
@@ -10305,8 +10299,7 @@ int cmpp__step(cmpp * const pp, sqlite3_stmt * const q, bool resetIt){
|
||||
from cmpp_rc_e. It specifically treats SQLITE_ROW and SQLITE_DONE
|
||||
as non-errors, returning 0 for those.
|
||||
*/
|
||||
static int cmpp__db_errcode(sqlite3 * const db, int sqliteCode);
|
||||
int cmpp__db_errcode(sqlite3 * const db, int sqliteCode){
|
||||
static int cmpp__db_errcode(sqlite3 * const db, int sqliteCode){
|
||||
(void)db;
|
||||
int rc = 0;
|
||||
switch(sqliteCode & 0xff){
|
||||
@@ -10345,7 +10338,7 @@ int cmpp__db_rc(cmpp *pp, int dbRc, char const *zMsg){
|
||||
pp, cmpp__db_errcode(pp->pimpl->db.dbh, dbRc),
|
||||
"SQLite error #%d: %s%s%s",
|
||||
dbRc,
|
||||
pp->pimpl->db.dbh
|
||||
pp->pimpl->db.dbh
|
||||
? sqlite3_errmsg(pp->pimpl->db.dbh)
|
||||
: "<no db handle>",
|
||||
zMsg ? ": " : "",
|
||||
@@ -10357,7 +10350,10 @@ int cmpp__db_rc(cmpp *pp, int dbRc, char const *zMsg){
|
||||
/**
|
||||
The base "define" impl. Requires q to be an INSERT for one of the
|
||||
define tables and have the (t,k,v) columns set up to bind to ?1,
|
||||
?2, and ?3.
|
||||
?2, and ?3. nVal must be the number of bytes of zVal to bind. If
|
||||
zVal is NULL then (zVal="1", nVal=1) is assumed, else if nVal is 0
|
||||
then zVal is bound as SQL NULL. That's wonky, but it's what we
|
||||
currently have.
|
||||
*/
|
||||
static
|
||||
int cmpp__define_impl(cmpp * const pp,
|
||||
@@ -10963,6 +10959,7 @@ static void cmpp_dx_f_define(cmpp_dx *dx){
|
||||
unsigned char acHeredoc[128] = {0} /* TODO: cmpp_args_clone() */;
|
||||
bool ifNotDefined = false /* true if '?' arg */;
|
||||
cmpp_arg const *aAppend = 0;
|
||||
bool raw = false;
|
||||
#define checkIsDefined(ARG) \
|
||||
if(ifNotDefined && (cmpp_has(dx->pp, (char const*)ARG->z, ARG->n) \
|
||||
|| dxppCode)) break
|
||||
@@ -11016,6 +11013,10 @@ static void cmpp_dx_f_define(cmpp_dx *dx){
|
||||
++nChomp;
|
||||
break;
|
||||
}
|
||||
if( cmpp_arg_isflag(arg,"-raw") ){
|
||||
raw = true;
|
||||
break;
|
||||
}
|
||||
if( cmpp_arg_isflag(arg,"-append")
|
||||
|| cmpp_arg_isflag(arg,"-a") ){
|
||||
aAppend = arg->next;
|
||||
@@ -11027,8 +11028,15 @@ static void cmpp_dx_f_define(cmpp_dx *dx){
|
||||
arg = aAppend;
|
||||
break;
|
||||
}
|
||||
handle_value:
|
||||
if( aKey ){
|
||||
/* This is the second arg - the value */
|
||||
if( arg->next ){
|
||||
cmpp_dx_err_set(dx, CMPP_RC_MISUSE,
|
||||
"Unexpected token after value: %s",
|
||||
arg->next->z);
|
||||
break;
|
||||
}
|
||||
checkIsDefined(aKey);
|
||||
cmpp_b * const os = cmpp_b_borrow(dx->pp);
|
||||
cmpp_b * const ba = aAppend ? cmpp_b_borrow(dx->pp) : 0;
|
||||
@@ -11048,6 +11056,8 @@ static void cmpp_dx_f_define(cmpp_dx *dx){
|
||||
if( ba->n ) cmpp_b_append4(dx->pp, ba, aAppend->z, aAppend->n);
|
||||
cmpp_b_append4(dx->pp, ba, os->z, os->n);
|
||||
}
|
||||
int n = nChomp;
|
||||
while( n-- && cmpp_b_chomp(which) ){}
|
||||
cmpp__define2(dx->pp, aKey->z, aKey->n, which->z, which->n,
|
||||
arg->ttype);
|
||||
if( 0 ){
|
||||
@@ -11073,7 +11083,10 @@ static void cmpp_dx_f_define(cmpp_dx *dx){
|
||||
break;
|
||||
case cmpp_TT_GroupSquiggly:
|
||||
assert( !acHeredoc[0] );
|
||||
if( (ifNotDefined ? argNdx>1 : argNdx>0) || arg->next ){
|
||||
if( aKey ){
|
||||
/* Treat this as a value */
|
||||
goto handle_value;
|
||||
}else if( (ifNotDefined ? argNdx>1 : argNdx>0) || arg->next ){
|
||||
cmpp_dx_err_set(dx, CMPP_RC_MISUSE,
|
||||
"{...} must be the only argument.")
|
||||
/* This is for simplicity's sake. */;
|
||||
@@ -11117,6 +11130,8 @@ static void cmpp_dx_f_define(cmpp_dx *dx){
|
||||
checkIsDefined(aKey);
|
||||
cmpp_b * const b = cmpp_b_borrow(dx->pp);
|
||||
if( b && 0==cmpp_call_str(dx->pp, arg->z, arg->n, b, 0) ){
|
||||
int n = nChomp;
|
||||
while( n-- && cmpp_b_chomp(b) ){}
|
||||
cmpp__define2(dx->pp, aKey->z, aKey->n,
|
||||
b->z, b->n, cmpp_TT_AnyType);
|
||||
}
|
||||
@@ -11131,17 +11146,15 @@ static void cmpp_dx_f_define(cmpp_dx *dx){
|
||||
break;
|
||||
}
|
||||
}
|
||||
if( 0==nHeredoc && nChomp ){
|
||||
cmpp_dx_err_set(dx, CMPP_RC_MISUSE,
|
||||
"-chomp can only be used with <<.");
|
||||
}
|
||||
if( 0==dxppCode && nHeredoc ){
|
||||
// Process (#define KEY <<)
|
||||
cmpp_b * const os = cmpp_b_borrow(dx->pp);
|
||||
assert( dx->d->closer );
|
||||
if( os &&
|
||||
0==cmpp_dx_consume_b(dx, os, &dx->d->closer, 1,
|
||||
cmpp_dx_consume_F_PROCESS_OTHER_D) ){
|
||||
raw
|
||||
? cmpp_dx_consume_F_RAW
|
||||
: cmpp_dx_consume_F_PROCESS_OTHER_D) ){
|
||||
while( nChomp-- && cmpp_b_chomp(os) ){}
|
||||
g_debug(dx->pp,2,("define heredoc: [%s]=[%.*s]\n",
|
||||
acHeredoc, (int)os->n, os->z));
|
||||
@@ -11191,6 +11204,153 @@ static void cmpp_dx_f_undef(cmpp_dx *dx){
|
||||
}
|
||||
}
|
||||
|
||||
/* Impl. for #expand. */
|
||||
static void cmpp_dx_f_expand(cmpp_dx *dx){
|
||||
cmpp_d const * const d = dx->d;
|
||||
assert(d);
|
||||
if( !dx->args.arg0 ){
|
||||
cmpp_dx_err_set(dx, CMPP_RC_MISUSE,
|
||||
"#expand requires one or two arguments");
|
||||
return;
|
||||
}
|
||||
cmpp_arg const * argKav = 0 /* {key -> value ...} */;
|
||||
cmpp_arg const * argToB = 0 /* one of X or Y from: #expand X Y */;
|
||||
cmpp_arg const * aLhs = 0;
|
||||
cmpp_arg const * aRhs = 0;
|
||||
cmpp_arg const * aErr = 0;
|
||||
cmpp_args args = cmpp_args_empty /* need a clone b/c of recursion */;
|
||||
cmpp_b * const osIn = cmpp_b_borrow(dx->pp);
|
||||
int nChomp = 0 /* Strip nChomp newlines from result */;
|
||||
int unChomp = 0 /* Add unChomp newlines to result */;
|
||||
bool raw = false /* interpret block content as raw or
|
||||
preprocessor-ready? */;
|
||||
bool inSp = false /* started a local savepoint? */;
|
||||
if( !osIn || cmpp_dx_args_clone(dx, &args) ) goto end;
|
||||
for( cmpp_arg const * arg = args.arg0;
|
||||
0==dxppCode && arg && !aRhs;
|
||||
arg = arg->next ){
|
||||
//g_warn("arg=%s", arg->z);
|
||||
aErr = arg;
|
||||
switch( arg->ttype ){
|
||||
case cmpp_TT_Word:
|
||||
if( cmpp_arg_isflag(arg,"-chomp") ){
|
||||
++nChomp;
|
||||
continue;
|
||||
}
|
||||
if( cmpp_arg_isflag(arg,"-unchomp") ){
|
||||
++unChomp;
|
||||
continue;
|
||||
}
|
||||
if( cmpp_arg_isflag(arg,"-raw") ){
|
||||
raw = true;
|
||||
continue;
|
||||
}
|
||||
if( !aLhs ){
|
||||
aLhs = arg;
|
||||
continue;
|
||||
}
|
||||
goto unexpected_arg;
|
||||
default:
|
||||
assert( !aRhs );
|
||||
if( aLhs ){
|
||||
if( (aErr = arg->next) ){
|
||||
assert( arg!=aLhs );
|
||||
assert( !aRhs );
|
||||
goto unexpected_arg;
|
||||
}
|
||||
aRhs = arg;
|
||||
}else{
|
||||
aLhs = arg;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if( !aLhs ){
|
||||
cmpp_dx_err_set(dx, CMPP_RC_MISUSE, "Expecting one or two arguments.");
|
||||
goto end;
|
||||
}
|
||||
if( aRhs ){
|
||||
if( cmpp_TT_GroupSquiggly!=aRhs->ttype ){
|
||||
aErr = aRhs;
|
||||
goto unexpected_arg;
|
||||
}
|
||||
argKav = aRhs;
|
||||
argToB = aLhs;
|
||||
}else{
|
||||
if( cmpp_TT_GroupSquiggly==aLhs->ttype ){
|
||||
argKav = aLhs;
|
||||
}else{
|
||||
argToB = aLhs;
|
||||
}
|
||||
}
|
||||
assert( argKav || argToB );
|
||||
if( argToB ){
|
||||
if( cmpp_arg_to_b(dx, argToB, osIn, cmpp_arg_to_b_F_BRACE_CALL) ){
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
if( argKav ){
|
||||
assert(!argKav->next);
|
||||
if( (aErr = argKav->next) ){
|
||||
goto unexpected_arg;
|
||||
}
|
||||
if( cmpp_sp_begin(dx->pp) ) goto end;
|
||||
inSp = true;
|
||||
if( cmpp_kav_each(dx, argKav->z, argKav->n,
|
||||
cmpp_kav_each_f_define__group,
|
||||
0,
|
||||
cmpp_kav_each_F_EXPAND_VAL
|
||||
| cmpp_kav_each_F_CALL_VAL
|
||||
| cmpp_kav_each_F_PARENS_EXPR) ){
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
if( argToB && cmpp_TT_GroupSquiggly==argToB->ttype ){
|
||||
cmpp_outputer xout = cmpp_outputer_b;
|
||||
cmpp_outputer old = {0};
|
||||
cmpp_b * const b = cmpp_b_borrow(dx->pp);
|
||||
if( !(xout.state = b) ) goto end;
|
||||
cmpp__outputer_swap(dx->pp, &xout, &old);
|
||||
cmpp_process_string(dx->pp, "#expand buffer", osIn->z, osIn->n);
|
||||
cmpp__outputer_swap(dx->pp, &old, &xout);
|
||||
cmpp_b_swap(b, osIn);
|
||||
cmpp_b_return(dx->pp, b);
|
||||
if( dxppCode ) goto end;
|
||||
}
|
||||
if( !argToB ){
|
||||
assert(!osIn->n);
|
||||
if( cmpp_dx_is_call(dx) ){
|
||||
cmpp_dx_err_set(dx, CMPP_RC_MISUSE,
|
||||
"#expand.../#expand is not legal for [call].");
|
||||
goto end;
|
||||
}
|
||||
if( cmpp_dx_consume_b(dx, osIn, &dx->d->closer, 1,
|
||||
raw
|
||||
? cmpp_dx_consume_F_RAW
|
||||
: cmpp_dx_consume_F_PROCESS_OTHER_D) ){
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
while( nChomp-- && cmpp_b_chomp(osIn) ){}
|
||||
while( unChomp-- && cmpp_b_append_ch(osIn, '\n') ){}
|
||||
//MARKER(("Emitting %d bytes: %.*s\n", (int)osIn->n, (int)osIn->n, osIn->z));
|
||||
cmpp_dx_out_expand(dx, NULL, osIn->z, osIn->n, cmpp_atpol_CURRENT);
|
||||
|
||||
end:
|
||||
if( inSp ){
|
||||
cmpp_sp_rollback(dx->pp);
|
||||
}
|
||||
cmpp_b_return(dx->pp, osIn);
|
||||
cmpp_args_cleanup(&args);
|
||||
return;
|
||||
unexpected_arg:
|
||||
assert( aErr );
|
||||
cmpp_dx_err_set(dx, CMPP_RC_MISUSE, "Unexpected argument: %.*s",
|
||||
(int)aErr->n, aErr->z);
|
||||
goto end;
|
||||
}
|
||||
|
||||
|
||||
/* Impl. for #once. */
|
||||
static void cmpp_dx_f_once(cmpp_dx *dx){
|
||||
cmpp_d const * const d = dx->d;
|
||||
@@ -11201,7 +11361,6 @@ static void cmpp_dx_f_once(cmpp_dx *dx){
|
||||
"Expecting no arguments");
|
||||
return;
|
||||
}
|
||||
cmpp_dx_pimpl * const dxp = dx->pimpl;
|
||||
cmpp_b * const b = cmpp_b_borrow(dx->pp);
|
||||
if( !b ) return;
|
||||
cmpp_b_append_ch(b, '#');
|
||||
@@ -11212,7 +11371,7 @@ static void cmpp_dx_f_once(cmpp_dx *dx){
|
||||
if( b->errCode
|
||||
|| dxppCode
|
||||
|| cmpp_b_append_ch(b, ':')
|
||||
|| cmpp_b_append_i32(b, (int)dxp->pos.lineNo) ){
|
||||
|| cmpp_b_append_i32(b, (int)dx->pimpl->pos.lineNo) ){
|
||||
goto end;
|
||||
}
|
||||
//g_debug(dx->pp,1,("#once key: %s", b->z));
|
||||
@@ -12896,6 +13055,7 @@ static void cmpp_dx_f_join(cmpp_dx *dx){
|
||||
cmpp_b_reuse(bSep),
|
||||
cmpp_arg_to_b_F_BRACE_CALL);
|
||||
arg = arg->next;
|
||||
/* FIXME: unescape bSep */
|
||||
continue;
|
||||
}
|
||||
//FLAG("-nl"){ addNl=true; continue; }
|
||||
@@ -13026,12 +13186,11 @@ static void cmpp_dx_f_cmp(cmpp_dx *dx){
|
||||
cmpp_arg_to_b(dx, arg, bR, a2bFlags);
|
||||
continue;
|
||||
}
|
||||
goto usage;
|
||||
break;
|
||||
}
|
||||
|
||||
if( cmpp_dx_err_check(dx) ) goto end;
|
||||
if( !bL->z || !bR->z ){
|
||||
usage:
|
||||
cmpp_dx_err_set(dx, CMPP_RC_MISUSE,
|
||||
"Usage: LHS RHS");
|
||||
goto end;
|
||||
@@ -13156,6 +13315,8 @@ int cmpp__d_delayed_load(cmpp *pp, char const *zName){
|
||||
M_IF_CORE("delimiter", cmpp_dx_f_delimiter, F_A_LIST,
|
||||
cmpp_dx_f_dangling_closer, 0);
|
||||
M_IF_CORE("error", cmpp_dx_f_error, F_A_RAW, 0, 0);
|
||||
M_IF_CORE("expand", cmpp_dx_f_expand, F_A_LIST,
|
||||
cmpp_dx_f_dangling_closer, 0);
|
||||
M_IF_CORE("expr", cmpp_dx_f_expr, F_EXPR, 0, 0);
|
||||
M_IF_CORE("join", cmpp_dx_f_join, F_A_LIST, 0, 0);
|
||||
M_IF_CORE("once", cmpp_dx_f_once, F_A_LIST | F_NC,
|
||||
@@ -14034,7 +14195,6 @@ int cmpp_args_parse(cmpp_dx * const dx,
|
||||
}
|
||||
unsigned char * zOut = buffer->z;
|
||||
unsigned char const * const zOutEnd = zOut + buffer->nAlloc - 1;
|
||||
cmpp_arg * prevArg = 0;
|
||||
#if !defined(NDEBUG)
|
||||
unsigned char const * const zReallocCheck = buffer->z;
|
||||
#endif
|
||||
@@ -14044,7 +14204,6 @@ int cmpp_args_parse(cmpp_dx * const dx,
|
||||
pArgs->arg0 = NULL;
|
||||
pArgs->argc = 0;
|
||||
for( int i = 0; zPos<zInEnd; ++i){
|
||||
//g_stderr("i=%d prevArg=%p\n",i, prevArg);
|
||||
cmpp_arg * const arg =
|
||||
CmppArgList_append(dx->pp, &pArgs->pimpl->argli);
|
||||
if( !arg ) return dxppCode;
|
||||
@@ -14086,16 +14245,21 @@ int cmpp_args_parse(cmpp_dx * const dx,
|
||||
default: break;
|
||||
}
|
||||
if( dxppCode ) break;
|
||||
if( prevArg ){
|
||||
assert( !prevArg->next );
|
||||
prevArg->next = arg;
|
||||
}
|
||||
prevArg = arg;
|
||||
}/*foreach input char*/
|
||||
//g_stderr("rc=%s argc=%d\n", cmpp_rc_cstr(dxppCode), pArgs->args.n);
|
||||
if( 0==dxppCode ){
|
||||
pArgs->argc = pArgs->pimpl->argli.n;
|
||||
assert( !pArgs->arg0 );
|
||||
for( unsigned int i = 0; i < pArgs->argc; ++i ){
|
||||
/* We have to link arg->next after the loop because
|
||||
CmppArgList_append() can realloc, invalidating
|
||||
the links. */
|
||||
if( i ){
|
||||
cmpp_arg * const a = &pArgs->pimpl->argli.list[i];
|
||||
assert( ! a->next );
|
||||
pArgs->pimpl->argli.list[i-1].next = a;
|
||||
}
|
||||
}
|
||||
if( pArgs->argc ) pArgs->arg0 = pArgs->pimpl->argli.list;
|
||||
if( zOut<zInEnd ) *zOut = 0;
|
||||
if( 0 ){
|
||||
|
||||
14
manifest
14
manifest
@@ -1,5 +1,5 @@
|
||||
C Improve\sperformance\sand\srobustness\sof\sinternal\sroutine\sjsonBlobExpand().
|
||||
D 2026-07-20T21:03:27.436
|
||||
C Latest\supstream\sext/wasm/libcmpp.c,\sprimarily\sto\smake\sit\sfilcc-legal\s(only\sthe\sfinal\schunk\sin\sthe\sdiff\s-\sthe\srest\sis\sminor\schanges\saccumulated\ssince\sthe\slast\supdate).
|
||||
D 2026-07-21T10:44:28.794
|
||||
F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x
|
||||
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
|
||||
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
|
||||
@@ -636,7 +636,7 @@ F ext/wasm/index-dist.html db23748044e286773f2768eec287669501703b5d5f72755e8db73
|
||||
F ext/wasm/index.html 5bf6cf1b0a3c8b9f5f54d77f2219d7ae87a15162055ce308109c49b1dcab4239
|
||||
F ext/wasm/jaccwabyt/jaccwabyt.js 4e2b797dc170851c9c530c3567679f4aa509eec0fab73b466d945b00b356574b
|
||||
F ext/wasm/jaccwabyt/jaccwabyt.md 6aa90fa1a973d0ad10d077088bea163b241d8470c75eafdef87620a1de1dea41
|
||||
F ext/wasm/libcmpp.c 0e2cec7de7c9cbe7941e6a4dc0c123cec736578a3eeae7828ac18706acd3cea6
|
||||
F ext/wasm/libcmpp.c e8ad0f9213af8edb19859e2b584ab6d5801a0e5e19fd715c9add269dfa720ee3
|
||||
F ext/wasm/mkdist.sh f8883b077a2ca47cf92e6f0ce305fbf72ca648c3501810125056c4b09c2d5554 x
|
||||
F ext/wasm/mkwasmbuilds.c 60706fb66db7f1e24d876e3cb2493484cfb27e7b103c7741c384505dd678769c
|
||||
F ext/wasm/module-symbols.html e54f42112e0aac2a31f850ab33e7f2630a2ea4f63496f484a12469a2501e07e2
|
||||
@@ -2217,8 +2217,8 @@ F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee
|
||||
F tool/warnings.sh a554d13f6e5cf3760f041b87939e3d616ec6961859c3245e8ef701d1eafc2ca2
|
||||
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
|
||||
F tool/winmain.c 00c8fb88e365c9017db14c73d3c78af62194d9644feaf60e220ab0f411f3604c
|
||||
P 6384b4b8720e35682c3ec01e7de6f0fcaec58026d5e07dfaf989f5e5851d9810
|
||||
R dca0e86070ed3e75ecf3f945925d415f
|
||||
U drh
|
||||
Z 8f5fa16b637811435deedb5237193d8e
|
||||
P 099af17c6f82d0a1357f4d3ec5967fb5c664ec532ddfa674017cb4d8041d45c3
|
||||
R 1b770928cd957473d7d5119d2d70cf68
|
||||
U stephan
|
||||
Z 98cce33760d403d951c7ab42f002d518
|
||||
# Remove this line to create a well-formed Fossil manifest.
|
||||
|
||||
@@ -1 +1 @@
|
||||
099af17c6f82d0a1357f4d3ec5967fb5c664ec532ddfa674017cb4d8041d45c3
|
||||
06f3bbc5bddc2e763042f8b487a3deedf47c54b7fa785ba6fd6abd524b4cbe3a
|
||||
|
||||
Reference in New Issue
Block a user