1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-10-21 11:13:54 +03:00

Latest upstream c-pp.c for the ability to process multiple inputs and outputs in a single invocation.

FossilOrigin-Name: c7633373046ceb94f293b8fbd4f436a1eb281c2744d97334c6e7e3a803d8eac2
This commit is contained in:
stephan
2025-09-27 00:04:28 +00:00
parent 879066a0a2
commit 836e895f9e
3 changed files with 200 additions and 102 deletions

View File

@@ -501,11 +501,13 @@ struct CmppTokenizer {
#define CLvl_skip(lvl) ((lvl)->skipLevel || ((lvl)->flags & CmppLevel_F_ELIDE))
#define CT_skip(t) CLvl_skip(&CT_level(t))
#define CmppTokenizer_empty_m { \
0,0,0,0,0,1U/*lineNo*/, \
TS_Start, \
CmppToken_empty_m, \
{/*level*/0U,{CmppLevel_empty_m}}, \
{/*args*/0,0,{0},{0}} \
.zName=0, .zBegin=0, .zEnd=0, .zAnchor=0, \
.zPos=0, \
.lineNo=1U, \
.pstate = TS_Start, \
.token = CmppToken_empty_m, \
.level = {0U,{CmppLevel_empty_m}}, \
.args = {0,0,{0},{0}} \
}
static const CmppTokenizer CmppTokenizer_empty = CmppTokenizer_empty_m;
@@ -555,17 +557,30 @@ static struct Global {
sqlite3_stmt * inclPathAdd;
sqlite3_stmt * inclSearch;
} stmt;
struct {
FILE * pFile;
int expandSql;
} sqlTrace;
} g = {
"?",
CMPP_DEFAULT_DELIM/*zDelim*/,
(unsigned short) sizeof(CMPP_DEFAULT_DELIM)-1/*nDelim*/,
0/*doDebug*/,
0/*db*/,
FileWrapper_empty_m/*out*/,
{/*stmt*/
0/*defIns*/, 0/*defDel*/, 0/*defHas*/,
0/*inclIns*/, 0/*inclDel*/, 0/*inclHas*/,
0/*inclPathAdd*/
.zArgv0 = "?",
.zDelim = CMPP_DEFAULT_DELIM,
.nDelim = (unsigned short) sizeof(CMPP_DEFAULT_DELIM)-1,
.doDebug = 0,
.db = 0,
.out = FileWrapper_empty_m,
.stmt = {
.defIns = 0,
.defDel = 0,
.defHas = 0,
.inclIns = 0,
.inclDel = 0,
.inclHas = 0,
.inclPathAdd = 0,
.inclSearch = 0
},
.sqlTrace = {
.pFile = 0,
.expandSql = 0
}
};
@@ -790,11 +805,19 @@ int db_define_has(const char * zName){
void db_define_rm(const char * zKey){
int rc;
int n = 0;
const char *zPos = zKey;
if(!g.stmt.defDel){
db_prepare(&g.stmt.defDel, "DELETE FROM def WHERE k=?");
//const char *zPos = zKey;
#if 0
if( !zKey ){
if( g.db ){
sqlite3_exec(g.db, "DELETE FROM def", 0, 0, 0);
}
for( ; *zPos && '='!=*zPos; ++n, ++zPos) {}
return;
}
#endif
if(!g.stmt.defDel){
db_prepare(&g.stmt.defDel, "DELETE FROM def WHERE k GLOB ?");
}
//for( ; *zPos && '='!=*zPos; ++n, ++zPos) {}
db_bind_text(g.stmt.defDel, 1, zKey);
rc = db_step(g.stmt.defDel);
if(SQLITE_DONE != rc){
@@ -818,7 +841,7 @@ void db_including_add(const char * zKey, const char * zSrc, int srcLine){
if(SQLITE_DONE != rc){
db_affirm_rc(rc, "Stepping INSERT on incl");
}
g_debug(2,("inclpath add [%s] from [%s]:%d\n", zKey, zSrc, srcLine));
g_debug(2,("is-including-file add [%s] from [%s]:%d\n", zKey, zSrc, srcLine));
sqlite3_clear_bindings(g.stmt.inclIns);
sqlite3_reset(g.stmt.inclIns);
}
@@ -934,6 +957,31 @@ static void udf_file_exists(
sqlite3_result_int(context, 0==access(zName, 0));
}
/**
This sqlite3_trace_v2() callback outputs tracing info using
whut_output().
*/
static int cmpp__db_sq3TraceV2(unsigned t,void*c,void*p,void*x){
static unsigned int counter = 0;
switch(t){
case SQLITE_TRACE_STMT:{
FILE * const fp = g.sqlTrace.pFile;
char const * zSql = (char const *)x;
char * zExp = g.sqlTrace.expandSql
? sqlite3_expanded_sql((sqlite3_stmt*)p)
: 0;
//MARKER(("mask=%08x isExp=%d\n", db->impl.event.maskIds, isExp));
assert( fp );
fprintf(fp, "SQL TRACE #%u: %s\n",
++counter, zExp ? zExp : zSql);
sqlite3_free(zExp);
break;
}
}
return 0;
}
/* Initialize g.db, failing fatally on error. */
static void cmpp_initdb(void){
int rc;
@@ -951,7 +999,7 @@ static void cmpp_initdb(void){
") WITHOUT ROWID;"
/* ^^^ files currently being included */
"CREATE TABLE inclpath("
"seq INTEGER UNIQUE, "
"seq INTEGER UNIQUE ON CONFLICT IGNORE, "
"dir TEXT PRIMARY KEY NOT NULL ON CONFLICT IGNORE"
")"
/* ^^^ include path */
@@ -960,6 +1008,9 @@ static void cmpp_initdb(void){
if(g.db) return;
rc = sqlite3_open_v2(":memory:", &g.db, SQLITE_OPEN_READWRITE, 0);
if(rc) fatal("Error opening :memory: db.");
if( g.sqlTrace.pFile ){
sqlite3_trace_v2(g.db, SQLITE_TRACE_STMT, cmpp__db_sq3TraceV2, 0);
}
rc = sqlite3_exec(g.db, zSchema, 0, 0, &zErr);
if(rc) fatal("Error initializing database: %s", zErr);
rc = sqlite3_create_function(g.db, "fileExists", 1,
@@ -1439,32 +1490,41 @@ void cmpp_process_file(const char * zName){
}
}
#undef CT_level
#undef CT_pstate
#undef CT_skipLevel
#undef CT_skip
#undef CLvl_skip
static void usage(int isErr){
FILE * const fOut = isErr ? stderr : stdout;
fprintf(fOut, "Usage: %s [flags] [infile...]\n", g.zArgv0);
fprintf(fOut,
"Usage: %s [flags] [infile...]\n"
"Flags:\n",
g.zArgv0);
"Flags and filenames may be in any order and "
"they are processed in that order.\n"
"\nFlags:\n\n");
#define arg(F,D) fprintf(fOut," %s\n %s\n",F, D)
arg("-o|--outfile FILE","Send output to FILE (default=- (stdout)). "
" Because arguments are processed in order, this should "
" normally be given before -f.");
arg("-f|--file FILE","Read input from FILE (default=- (stdin)).\n"
" Alternately, non-flag arguments are assumed to "
"be the input files.");
arg("-o|--outfile FILE","Send output to FILE (default=- (stdout))");
" All non-flag arguments are assumed to be the input files.");
arg("-DXYZ","Define XYZ to true");
arg("-UXYZ","Undefine XYZ (equivalent to false)");
arg("-UXYZ","Undefine all matching glob XYZ");
arg("-IXYZ","Add dir XYZ to include path");
arg("-d|--delimiter VALUE", "Set keyword delimiter to VALUE "
"(default=" CMPP_DEFAULT_DELIM ")");
arg("--sql-trace", "Send a trace of all SQL to stderr");
arg("--sql-trace-x", "Like --sql-trace but expand the SQL");
#undef arg
fputs("",fOut);
}
int main(int argc, char const * const * argv){
int rc = 0;
int i;
int inclCount = 0;
int nFile = 0;
char const *zFileList[128] = {0};
#define M(X) (0==strcmp(X,zArg))
#define ISFLAG(X) else if(M(X))
#define ISFLAG2(X,Y) else if(M(X) || M(Y))
@@ -1472,74 +1532,112 @@ int main(int argc, char const * const * argv){
if(i+1>=argc) fatal("Missing value for flag '%s'", zArg); \
zArg = argv[++i]
memset(zFileList, 0, sizeof(zFileList));
g.zArgv0 = argv[0];
#define DOIT if(doIt)
for(int doIt = 0; doIt<2; ++doIt){
/**
Loop through the flags twice. The first time we just validate
and look for --help/-?. The second time we process the flags.
This approach allows us to easily chain multiple files and
flags:
./c-pp -Dfoo -o foo x.y -Ufoo -Dbar -o bar x.y
*/
DOIT{
atexit(cmpp_atexit);
cmpp_initdb();
for(i = 1; i < argc; ++i){
}
for(int i = 1; i < argc; ++i){
char const * zArg = argv[i];
while('-'==*zArg) ++zArg;
if(M("?") || M("help")) {
if(zArg==argv[i]/*not a flag*/){
goto do_infile;
}ISFLAG2("?","help"){
usage(0);
goto end;
}else if('D'==*zArg){
++zArg;
if(!*zArg) fatal("Missing key for -D");
DOIT {
db_define_add(zArg);
}
}else if('U'==*zArg){
++zArg;
if(!*zArg) fatal("Missing key for -U");
DOIT {
db_define_rm(zArg);
}
}else if('I'==*zArg){
++zArg;
if(!*zArg) fatal("Missing directory for -I");
DOIT {
db_include_dir_add(zArg);
++inclCount;
}
}
ISFLAG2("o","outfile"){
ARGVAL;
if(g.out.zName) fatal("Cannot use -o more than once.");
g.out.zName = zArg;
DOIT {
FileWrapper_open(&g.out, zArg, "w");
}
}
ISFLAG2("f","file"){
ARGVAL;
do_infile:
if( nFile>=sizeof(zFileList)/sizeof(zFileList[0]) ){
fatal("Too many file arguments. Max is %d.",
(int)(sizeof(zFileList)/sizeof(zFileList[0])));
DOIT {
++nFile;
if(!g.out.pFile) FileWrapper_open(&g.out, "-", "w");
if(!inclCount){
db_include_dir_add(".");
++inclCount;
}
cmpp_process_file(zArg);
}
zFileList[nFile++] = zArg;
}
ISFLAG2("d","delimiter"){
ARGVAL;
if( !doIt ){
g.zDelim = zArg;
g.nDelim = (unsigned short)strlen(zArg);
if(!g.nDelim) fatal("Keyword delimiter may not be empty.");
}
}
ISFLAG("debug"){
DOIT {
++g.doDebug;
}else if(zArg==argv[i]/*not a flag*/){
goto do_infile;
}else{
}
}
ISFLAG("sql-trace"){
if( !doIt ){
/* Needs to be set before the start of the second pass, when
the db is inited. */
g.sqlTrace.pFile = stderr;
g.sqlTrace.expandSql = 0;
}
}
ISFLAG("sql-trace-x"){
if( !doIt ){
g.sqlTrace.pFile = stderr;
g.sqlTrace.expandSql = 1;
}
}
else{
fatal("Unhandled flag: %s", argv[i]);
}
}
DOIT {
if(!nFile){
zFileList[nFile++] = "-";
}
if(!g.out.zName) g.out.zName = "-";
if(!inclCount) db_include_dir_add(".");
FileWrapper_open(&g.out, g.out.zName, "w");
for(i = 0; i < nFile; ++i){
cmpp_process_file(zFileList[i]);
if(!inclCount){
db_include_dir_add(".");
++inclCount;
}
FileWrapper_open(&g.out, g.out.zName, "w");
cmpp_process_file("-");
}
}
}
FileWrapper_close(&g.out);
end:
FileWrapper_close(&g.out);
return rc ? EXIT_FAILURE : EXIT_SUCCESS;
}
#undef CT_level
#undef CT_pstate
#undef CT_skipLevel
#undef CT_skip
#undef CLvl_skip

View File

@@ -1,5 +1,5 @@
C Delay\sreplacing\sthe\swasm\sfile\sname\sstrings\suntil\sthey're\sneeded.\sAdd\starget\sb-all\sto\srun\sall\sknown\swasm\sbuilds.
D 2025-09-26T19:41:07.340
C Latest\supstream\sc-pp.c\sfor\sthe\sability\sto\sprocess\smultiple\sinputs\sand\soutputs\sin\sa\ssingle\sinvocation.
D 2025-09-27T00:04:28.087
F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
@@ -610,7 +610,7 @@ F ext/wasm/api/sqlite3-vtab-helper.c-pp.js 9097074724172e31e56ce20ccd7482259cf72
F ext/wasm/api/sqlite3-wasm.c ff2dc011e17b06186b8b35e408626d7ace69a362b92c197a34d78bef25c7105a
F ext/wasm/api/sqlite3-worker1-promiser.c-pp.js 8fb6adfbae6270344f43f2652e63780df3f86521755bde8f92cf6b809ba7891d
F ext/wasm/api/sqlite3-worker1.c-pp.js 69483df1df2d0988e708390f7b1feda769c16e9e9efd4683557f8e7197099cc0
F ext/wasm/c-pp.c 5f7e5bfe46105251bd7f892dd38ad57080dc65589760dac57c19b06d060c6828
F ext/wasm/c-pp.c f936676f82e5fef6550b52dfded40c46a603c4ba63ae544b989da83467c7d7a0
F ext/wasm/common/SqliteTestUtil.js 7adaeffef757d8708418dc9190f72df22367b531831775804b31598b44f6aa51
F ext/wasm/common/emscripten.css 11bd104b6c0d597c67d40cc8ecc0a60dae2b965151e3b6a37fa5708bac3acd15
F ext/wasm/common/testing.css e97549bab24126c24e0daabfe2de9bb478fb0a69fdb2ddd0a73a992c091aad6f
@@ -2169,8 +2169,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350
F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7
F tool/warnings.sh 1ad0169b022b280bcaaf94a7fa231591be96b514230ab5c98fbf15cd7df842dd
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
P 1078aa4f1e5685d45e31eea622865ddd077f367f1cec90fc267e8ba50cbe2ee9
R b65f3059fdd3f1d5877924b91516a2b0
P a4edaecc9b0b649df53a99e05d9abfbc5bdb40d45c7c6940a50b24fa30dca158
R bef2f9129a58747558af60f4197c21ac
U stephan
Z 4ba1230dbb68926ec3e296b074eb91b5
Z 316e05b3238d4a7d73024ef26d080321
# Remove this line to create a well-formed Fossil manifest.

View File

@@ -1 +1 @@
a4edaecc9b0b649df53a99e05d9abfbc5bdb40d45c7c6940a50b24fa30dca158
c7633373046ceb94f293b8fbd4f436a1eb281c2744d97334c6e7e3a803d8eac2