From: larrybr Date: Wed, 17 May 2023 03:57:12 +0000 (+0000) Subject: Further CLI resmanage use. (69% by LOC, 53% by command count) Some renames for clarity. X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=51d385df85dc26b7feab3387a68ca944af15398a;p=thirdparty%2Fsqlite.git Further CLI resmanage use. (69% by LOC, 53% by command count) Some renames for clarity. FossilOrigin-Name: c010e1a7b2120d44c096b7d4216a8a51601972581f232d537b577617dfa6195a --- diff --git a/manifest b/manifest index f29654a599..40f8523caf 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Further\sextend\suse\sof\sCLI\sresmanage.\s(40%\sof\sdot\scommands) -D 2023-05-16T20:37:38.246 +C Further\sCLI\sresmanage\suse.\s(69%\sby\sLOC,\s53%\sby\scommand\scount)\sSome\srenames\sfor\sclarity. +D 2023-05-17T03:57:12.866 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -638,12 +638,12 @@ F src/pragma.h e690a356c18e98414d2e870ea791c1be1545a714ba623719deb63f7f226d8bb7 F src/prepare.c 6350675966bd0e7ac3a464af9dbfe26db6f0d4237f4e1f1acdb17b12ad371e6e F src/printf.c b9320cdbeca0b336c3f139fd36dd121e4167dd62b35fbe9ccaa9bab44c0af38d F src/random.c 606b00941a1d7dd09c381d3279a058d771f406c5213c9932bbd93d5587be4b9c -F src/resmanage.c 5bea79cfe8b41b68489aed39f135270c937133338937088d2336dea3c005215d -F src/resmanage.h 28a5f41d55cc6d159cb14977e162de3c265ae8798d51ccd942fd218624195d99 +F src/resmanage.c 8fbaf2c6af64db4ce5fa2cdd97ce89415575ecb3d2984978214275b414bb5724 +F src/resmanage.h 755e58c5b0ee03a3fd11c019c4003242b01524c3bba4e4521439bd00564eccfa F src/resolve.c 3e53e02ce87c9582bd7e7d22f13f4094a271678d9dc72820fa257a2abb5e4032 F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92 F src/select.c 738c3a3d6929f8be66c319bad17f6b297bd60a4eb14006075c48a28487dc7786 -F src/shell.c.in a12f9ed7617194f2a09493d4fa83ac232303dd9a0a607988c2f05190aa842818 +F src/shell.c.in 19c383fbbbc2198cb7047de523a0c57c2328dd839ca03340ca7eae1ee804db26 F src/shext_linkage.h 27dcf7624df05b2a7a6d367834339a6db3636f3035157f641f7db2ec499f8f6d F src/sqlite.h.in c14a4471fcd897a03631ac7ad3d05505e895e7b6419ec5b96cae9bc4df7a9fc6 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 @@ -2081,8 +2081,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 243085279c6f8c51ad85bdc1e7c07ef6f858067640a7330f77d0bf94ed11b438 831d0fb2836b71c9bc51067c49fee4b8f18047814f2ff22d817d25195cf350b0 -R 932236b86f0cebfd2719e06bd539117f +P 0cdab9f17a2ceaa4d4228e535c3d780ed5fd2cb4e36cc50becba99e8ebff362d +R dcacca614f0ea4561b47767a0b44bde3 U larrybr -Z 2527b5a4612bc8b8d004f77ba865da77 +Z 17f12779e20d1bf08e9f288d6ce2800a # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index e4dddb57c1..3b19e333b2 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -0cdab9f17a2ceaa4d4228e535c3d780ed5fd2cb4e36cc50becba99e8ebff362d \ No newline at end of file +c010e1a7b2120d44c096b7d4216a8a51601972581f232d537b577617dfa6195a \ No newline at end of file diff --git a/src/resmanage.c b/src/resmanage.c index 41945e33f3..6d121d6808 100644 --- a/src/resmanage.c +++ b/src/resmanage.c @@ -22,8 +22,8 @@ /* Track how to free various held resources. */ typedef enum FreeableResourceKind { FRK_Indirect = 1<<15, - FRK_Malloc = 0, FRK_DbConn = 1, FRK_DbStmt = 2, - FRK_DbMem = 3, FRK_File = 4, + FRK_Malloc = 0, FRK_DbConn, FRK_DbStmt, FRK_SqStr, + FRK_DbMem, FRK_File, #if (!defined(_WIN32) && !defined(WIN32)) || !SQLITE_OS_WINRT FRK_Pipe, #endif @@ -56,6 +56,7 @@ typedef struct ResourceHeld { #ifdef SHELL_MANAGE_TEXT ShellText *p_text; #endif + sqlite3_str *p_sqst; AnyResourceHolder *p_any_rh; VirtualDtorNthObject *p_vdfo; } held; @@ -100,10 +101,12 @@ void quit_moan(const char *zMoan, int errCode){ /* Free a single resource item. (ignorant of stack) */ static int free_rk( ResourceHeld *pRH ){ int rv = 0; - if( pRH->held.p_any == 0 ) return rv; + if( pRH->held.p_any == 0 ) return 0; if( pRH->frk & FRK_Indirect ){ - pRH->held.p_any = *(void**)pRH->held.p_any; - if( pRH->held.p_any == 0 ) return rv; + void **ppv = (void**)pRH->held.p_any; + pRH->held.p_any = *ppv; + *ppv = (void*)0; + if( pRH->held.p_any == 0 ) return 0; pRH->frk &= ~FRK_Indirect; } ++rv; @@ -134,6 +137,12 @@ static int free_rk( ResourceHeld *pRH ){ freeText(pRH->held.p_text); break; #endif + case FRK_SqStr: + { + char *z = sqlite3_str_finish(pRH->held.p_sqst); + if( z!=0 ) sqlite3_free(z); + } + break; case FRK_AnyRef: (pRH->held.p_any_rh->its_freer)(pRH->held.p_any_rh->pAny); break; @@ -183,12 +192,12 @@ static int more_holders_try(ResourceCount count){ } /* Lose one or more holders. */ -void* pop_holder(void){ +void* drop_holder(void){ assert(numResHold>0); if( numResHold>0 ) return pResHold[--numResHold].held.p_any; return 0; } -void pop_holders(ResourceCount num){ +void drop_holders(ResourceCount num){ assert(numResHold>=num); if( numResHold>=num ) numResHold -= num; else numResHold = 0; @@ -235,11 +244,21 @@ char* mstr_holder(char *z){ res_hold(z, FRK_Malloc); return z; } +/* Hold a SQLite dynamic string */ +sqlite3_str * sqst_holder(sqlite3_str *psqst){ + res_hold(psqst, FRK_SqStr); + return psqst; +} /* Hold a C string in the SQLite heap */ char* sstr_holder(char *z){ res_hold(z, FRK_DbMem); return z; } +/* Hold a SQLite dynamic string, reference to */ +void sqst_ptr_holder(sqlite3_str **ppsqst){ + assert(ppsqst!=0); + res_hold(ppsqst, FRK_SqStr|FRK_Indirect); +} /* Hold a C string in the SQLite heap, reference to */ void sstr_ptr_holder(char **pz){ assert(pz!=0); diff --git a/src/resmanage.h b/src/resmanage.h index eb6907c12b..f269bf9c2f 100644 --- a/src/resmanage.h +++ b/src/resmanage.h @@ -82,8 +82,8 @@ extern ResourceMark holder_mark(); extern void more_holders(ResourceCount more); /* Lose one or more holders, without freeing anything. */ -extern void* pop_holder(void); -extern void pop_holders(ResourceCount num); +extern void* drop_holder(void); +extern void drop_holders(ResourceCount num); /* Drop one or more holders while freeing their holdees. */ extern void release_holder(void); @@ -110,6 +110,8 @@ extern char* sstr_holder(char *z); extern void conn_holder(sqlite3 *pdb); /* a SQLite prepared statement */ extern void stmt_holder(sqlite3_stmt *pstmt); +/* a SQLite dynamic string */ +extern sqlite3_str *sqst_holder(sqlite3_str *psqst); /* an open C runtime FILE */ extern void file_holder(FILE *); #if (!defined(_WIN32) && !defined(WIN32)) || !SQLITE_OS_WINRT @@ -148,7 +150,9 @@ extern void sstr_ptr_holder(char **pz); extern void stmt_ptr_holder(sqlite3_stmt **ppstmt); /* a SQLite database ("connection"), reference to */ extern void conn_ptr_holder(sqlite3 **ppdb); -/* an object with v-table (ref) whose dtor is the 0th member, reference to */ +/* a SQLite dynamic string, reference to */ +extern void sqst_ptr_holder(sqlite3_str **ppsqst); +/* an object with (by-ref) v-table whose dtor is nth member, reference to */ extern void dtor_ref_holder(VirtualDtorNthObject *pvdfo, unsigned char n); #ifdef SHELL_MANAGE_TEXT /* a ShellText object, reference to (storage for which not managed) */ diff --git a/src/shell.c.in b/src/shell.c.in index c865a3d497..db0c74bcff 100644 --- a/src/shell.c.in +++ b/src/shell.c.in @@ -5820,7 +5820,7 @@ static unsigned char *readHexDb(ShellInState *psi, int *pnData){ } } *pnData = n; /* Record success and size. */ - pop_holder(); + drop_holder(); readHexDb_cleanup: holder_free(mark); return a; @@ -10643,7 +10643,7 @@ DISPATCHABLE_COMMAND( import ? 3 7 ){ "%s\n", sCtx.zFile, zRenames); } assert(dbCols==0); - pop_holder(); /* dbCols */ + drop_holder(); /* dbCols */ if( zColDefs==0 ){ *pzErr = smprintf("%s: empty file\n", sCtx.zFile); import_fail: /* entry from outer blocks */ @@ -10816,14 +10816,16 @@ COLLECT_HELP_TEXT[ ]; DISPATCHABLE_COMMAND( imposter ? 3 3 ){ int rc = 0; - char *zSql; + char *zSql = 0; char *zCollist = 0; - sqlite3_stmt *pStmt; + sqlite3_stmt *pStmt = 0; sqlite3 *db; int tnum = 0; int isWO = 0; /* True if making an imposter of a WITHOUT ROWID table */ int lenPK = 0; /* Length of the PRIMARY KEY string for isWO tables */ int i; + ResourceMark mark = holder_mark(); + if( !ShellHasFlag(p,SHFLG_TestingMode) ){ utf8_printf(stderr, ".%s unavailable without --unsafe-testing\n", "imposter"); @@ -10847,6 +10849,7 @@ DISPATCHABLE_COMMAND( imposter ? 3 3 ){ sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, db, "main", 0, 1); return DCR_Ok; } + sstr_ptr_holder(&zSql); zSql = smprintf("SELECT rootpage, 0 FROM sqlite_schema" " WHERE name='%q' AND type='index'" "UNION ALL " @@ -10854,17 +10857,24 @@ DISPATCHABLE_COMMAND( imposter ? 3 3 ){ " WHERE name='%q' AND type='table'" " AND sql LIKE '%%without%%rowid%%'", azArg[1], azArg[1]); - sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0); - sqlite3_free(zSql); + shell_check_ooms(zSql); + rc = shell_check_nomem(sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0)); + if( rc!=SQLITE_OK ){ + release_holder(); + return DCR_Error; + } + stmt_ptr_holder(&pStmt); if( sqlite3_step(pStmt)==SQLITE_ROW ){ tnum = sqlite3_column_int(pStmt, 0); isWO = sqlite3_column_int(pStmt, 1); } - sqlite3_finalize(pStmt); - zSql = smprintf("PRAGMA index_xinfo='%q'", azArg[1]); - rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0); sqlite3_free(zSql); + zSql = smprintf("PRAGMA index_xinfo='%q'", azArg[1]); + sqlite3_finalize(pStmt); + pStmt = 0; + rc = shell_check_nomem(sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0)); i = 0; + sstr_ptr_holder(&zCollist); while( rc==SQLITE_OK && sqlite3_step(pStmt)==SQLITE_ROW ){ char zLabel[20]; const char *zCol = (const char*)sqlite3_column_text(pStmt,2); @@ -10886,19 +10896,19 @@ DISPATCHABLE_COMMAND( imposter ? 3 3 ){ zCollist = smprintf("%z,\"%w\"", zCollist, zCol); } } - sqlite3_finalize(pStmt); if( i==0 || tnum==0 ){ *pzErr = smprintf("no such index: \"%s\"\n", azArg[1]); - sqlite3_free(zCollist); + holder_free(mark); return DCR_Error; } if( lenPK==0 ) lenPK = 100000; + sqlite3_free(zSql); zSql = smprintf("CREATE TABLE \"%w\"(%s,PRIMARY KEY(%.*s))" "WITHOUT ROWID", azArg[2], zCollist, lenPK, zCollist); - sqlite3_free(zCollist); + shell_check_ooms(zSql); rc = sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, db, "main", 1, tnum); if( rc==SQLITE_OK ){ - rc = sqlite3_exec(db, zSql, 0, 0, 0); + rc = shell_check_nomem(sqlite3_exec(db, zSql, 0, 0, 0)); sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, db, "main", 0, 0); if( rc ){ *pzErr = smprintf("Error in [%s]: %s\n", zSql, sqlite3_errmsg(db)); @@ -10912,8 +10922,8 @@ DISPATCHABLE_COMMAND( imposter ? 3 3 ){ }else{ *pzErr = smprintf("SQLITE_TESTCTRL_IMPOSTER returns %d\n", rc); } - sqlite3_free(zSql); - return rc != 0; + holder_free(mark); + return DCR_Ok|(rc != 0); } DISPATCHABLE_COMMAND( iotrace ? 2 2 ){ SQLITE_API extern void (SQLITE_CDECL *sqlite3IoTrace)(const char*, ...); @@ -11012,6 +11022,7 @@ DISPATCHABLE_COMMAND( lint 3 1 0 ){ const char *zIndent = ""; /* How much to indent CREATE INDEX by */ int rc; /* Return code */ sqlite3_stmt *pSql = 0; /* Compiled version of SQL statement below */ + ResourceMark mark = holder_mark(); i = (nArg>=2 ? strlen30(azArg[1]) : 0); if( i==0 || 0!=sqlite3_strnicmp(azArg[1], "fkey-indexes", i) ){ @@ -11111,8 +11122,10 @@ DISPATCHABLE_COMMAND( lint 3 1 0 ){ ); if( rc==SQLITE_OK ){ - rc = sqlite3_prepare_v2(db, zSql, -1, &pSql, 0); + rc = shell_check_nomem(sqlite3_prepare_v2(db, zSql, -1, &pSql, 0)); } + /* Track resources after here. */ + stmt_ptr_holder(&pSql); if( rc==SQLITE_OK ){ sqlite3_bind_int(pSql, 1, bGroupByParent); } @@ -11120,9 +11133,11 @@ DISPATCHABLE_COMMAND( lint 3 1 0 ){ if( rc==SQLITE_OK ){ int rc2; char *zPrev = 0; + sqlite3_stmt *pExplain = 0; + sstr_ptr_holder(&zPrev); + stmt_ptr_holder(&pExplain); while( SQLITE_ROW==sqlite3_step(pSql) ){ int res = -1; - sqlite3_stmt *pExplain = 0; const char *zEQP = (const char*)sqlite3_column_text(pSql, 0); const char *zGlob = (const char*)sqlite3_column_text(pSql, 1); const char *zFrom = (const char*)sqlite3_column_text(pSql, 2); @@ -11131,14 +11146,16 @@ DISPATCHABLE_COMMAND( lint 3 1 0 ){ const char *zParent = (const char*)sqlite3_column_text(pSql, 5); if( zEQP==0 || zGlob==0 ) continue; - rc = sqlite3_prepare_v2(db, zEQP, -1, &pExplain, 0); + rc = shell_check_nomem(sqlite3_prepare_v2(db, zEQP, -1, &pExplain, 0)); if( rc!=SQLITE_OK ) break; if( SQLITE_ROW==sqlite3_step(pExplain) ){ const char *zPlan = (const char*)sqlite3_column_text(pExplain, 3); + shell_check_ooms(zPlan); res = zPlan!=0 && ( 0==sqlite3_strglob(zGlob, zPlan) || 0==sqlite3_strglob(zGlobIPK, zPlan)); } rc = sqlite3_finalize(pExplain); + pExplain = 0; if( rc!=SQLITE_OK ) break; if( res<0 ){ @@ -11152,6 +11169,7 @@ DISPATCHABLE_COMMAND( lint 3 1 0 ){ raw_printf(out, "-- Parent table %s\n", zParent); sqlite3_free(zPrev); zPrev = smprintf("%s", zParent); + shell_check_ooms(zPrev); } if( res==0 ){ @@ -11162,13 +11180,13 @@ DISPATCHABLE_COMMAND( lint 3 1 0 ){ } } } - sqlite3_free(zPrev); if( rc!=SQLITE_OK ){ *pzErr = smprintf("%s\n", sqlite3_errmsg(db)); } rc2 = sqlite3_finalize(pSql); + pSql = 0; if( rc==SQLITE_OK && rc2!=SQLITE_OK ){ rc = rc2; *pzErr = smprintf("%s\n", sqlite3_errmsg(db)); @@ -11176,6 +11194,7 @@ DISPATCHABLE_COMMAND( lint 3 1 0 ){ }else{ *pzErr = smprintf("%s\n", sqlite3_errmsg(db)); } + holder_free(mark); return DCR_Ok|(rc!=0); } @@ -11203,21 +11222,19 @@ DISPATCHABLE_COMMAND( log ? 2 2 ){ const char *zFile = azArg[1]; int bOn = cli_strcmp(zFile,"on")==0; int bOff = cli_strcmp(zFile,"off")==0; - if( ISS(p)->bSafeMode && !bOn && !bOff ){ - return DCR_AbortError; - } +#if defined(SQLITE_SHELL_FIDDLE) + if( !bOn && !bOff ) return DCR_SayUsage; +#else + if( ISS(p)->bSafeMode && !bOn && !bOff ) return DCR_AbortError; +#endif output_file_close(ISS(p)->pLog); if( bOff ){ ISS(p)->pLog = 0; return DCR_Ok; } -#if defined(SQLITE_SHELL_FIDDLE) - if( !bOn ) return DCR_SayUsage; -#else if( bOn ) zFile = "stdout"; -#endif ISS(p)->pLog = output_file_open(zFile, 0); - return DCR_Ok; + return DCR_Ok|(ISS(p)->pLog==0); } static void effectMode(ShellInState *psi, u8 modeRequest, u8 modeNominal){ @@ -11439,7 +11456,6 @@ DISPATCHABLE_COMMAND( oomfake ? 1 2 azArg nArg p ){ #else # define HOPEN ".open" #endif -/* ToDo: Get defined help text collection into macro processor. */ /***************** * The .nonce, .nullvalue and .open commands */ @@ -11546,8 +11562,7 @@ DISPATCHABLE_COMMAND( open 3 1 0 ){ psi->szMax = szMax; open_db(p, OPEN_DB_KEEPALIVE); if( DBX(p)==0 ){ - *pzErr = smprintf("cannot open '%s'\n", zNewFilename); - sqlite3_free(zNewFilename); + *pzErr = smprintf("cannot open '%z'\n", zNewFilename); rc = 1; }else{ psi->pAuxDb->zFreeOnClose = zNewFilename; @@ -11566,7 +11581,8 @@ DISPATCHABLE_COMMAND( nonce ? 2 2 ){ if( psi->zNonce==0 || cli_strcmp(azArg[1],psi->zNonce)!=0 ){ raw_printf(STD_ERR, "line %d: incorrect nonce: \"%s\"\n", psi->pInSource->lineno, azArg[1]); - exit(1); + p->shellAbruptExit = 0x102; + return DCR_Abort; } /* Suspend safe mode for 1 dot-command after this. */ psi->bSafeModeFuture = 2; @@ -11643,14 +11659,14 @@ static char *home_based_path( const char *zPath ){ static int kv_xfr_table(sqlite3 *db, const char *zStoreDbName, int bSaveNotLoad, ParamTableUse ptu, const char *azNames[], int nNames){ - int rc = 0; char *zSql = 0; /* to be sqlite3_free()'ed */ sqlite3_str *sbCopy = 0; + sqlite3 *dbStore = 0; const char *zHere = 0; const char *zThere = SH_KV_STORE_SNAME; const char *zTo; const char *zFrom; - sqlite3 *dbStore = 0; + int rc = 0; int openFlags = (bSaveNotLoad) ? SQLITE_OPEN_URI|SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE : SQLITE_OPEN_READONLY; @@ -11663,7 +11679,7 @@ static int kv_xfr_table(sqlite3 *db, const char *zStoreDbName, zTo = (bSaveNotLoad)? zThere : zHere; zFrom = (bSaveNotLoad)? zHere : zThere; /* Ensure store DB can be opened and/or created appropriately. */ - rc = sqlite3_open_v2(zStoreDbName, &dbStore, openFlags, 0); + rc = shell_check_nomem(sqlite3_open_v2(zStoreDbName,&dbStore,openFlags,0)); if( rc!=SQLITE_OK ){ utf8_printf(STD_ERR, "Error: Cannot %s key/value store DB %s\n", bSaveNotLoad? "open/create" : "read", zStoreDbName); @@ -11671,6 +11687,7 @@ static int kv_xfr_table(sqlite3 *db, const char *zStoreDbName, } /* Ensure it has the kv store table, or handle its absence. */ assert(dbStore!=0); + conn_ptr_holder(&dbStore); if( sqlite3_table_column_metadata (dbStore, "main", SH_KV_STORE_NAME, 0, 0, 0, 0, 0, 0)!=SQLITE_OK ){ if( !bSaveNotLoad ){ @@ -11685,32 +11702,37 @@ static int kv_xfr_table(sqlite3 *db, const char *zStoreDbName, " value,\n" " uses INT\n" ") WITHOUT ROWID;"; - rc = sqlite3_exec(dbStore, zCT, 0, 0, 0); + rc = shell_check_nomem(sqlite3_exec(dbStore, zCT, 0, 0, 0)); if( rc!=SQLITE_OK ){ utf8_printf(STD_ERR, "Cannot create table %s. Nothing saved.", zThere); } } } - sqlite3_close(dbStore); + release_holder(); + assert(dbStore==0); if( rc!=0 ) return rc; zSql = smprintf("ATTACH %Q AS %s;", zStoreDbName, SH_KV_STORE_SCHEMA); shell_check_ooms(zSql); + sstr_ptr_holder(&zSql); rc = sqlite3_exec(db, zSql, 0, 0, 0); - sqlite3_free(zSql); + release_holder(); if( rc!=SQLITE_OK ) return rc; sbCopy = sqlite3_str_new(db); + sqst_ptr_holder(&sbCopy); sqlite3_str_appendf (sbCopy, "INSERT OR REPLACE INTO %s(key,value,uses)" "SELECT key, value, uses FROM %s WHERE key ", zTo, zFrom); append_in_clause(sbCopy, azNames, azNames+nNames); zSql = sqlite3_str_finish(sbCopy); + drop_holder(); shell_check_ooms(zSql); + sstr_ptr_holder(&zSql); rc = sqlite3_exec(db, zSql, 0, 0, 0); - sqlite3_free(zSql); + release_holder(); - sqlite3_exec(db, "DETACH "SH_KV_STORE_SCHEMA";", 0, 0, 0); + shell_check_nomem(sqlite3_exec(db, "DETACH "SH_KV_STORE_SCHEMA";", 0, 0, 0)); return rc; } @@ -11722,10 +11744,9 @@ static const char *zDefaultVarStore = "~/sqlite_vars.sdb"; * and conversion of leading (or only) tilde as home directory. * The above-set default is used for zSpec NULL, "" or "~". * When return is 0, there is an error; what needs doing cannnot be done. - * If the return is exactly the input, it must not be sqlite3_free()'ed. - * If the return differs from the input, it must be sqlite3_free()'ed. + * The return must eventually be sqlite3_free()'ed. */ - static const char *kv_store_path(const char *zSpec, ParamTableUse ptu){ +static char *kv_store_path(const char *zSpec, ParamTableUse ptu){ if( zSpec==0 || zSpec[0]==0 || cli_strcmp(zSpec,"~")==0 ){ const char *zDef; switch( ptu ){ @@ -11737,21 +11758,23 @@ static const char *zDefaultVarStore = "~/sqlite_vars.sdb"; }else if ( zSpec[0]=='~' ){ return home_based_path(zSpec); } - return zSpec; + return smprintf("%s", zSpec); } /* Load some or all kv pairs. Arguments are "load FILE ?NAMES?". */ static int kv_pairs_load(sqlite3 *db, ParamTableUse ptu, const char *azArg[], int nArg){ - const char *zStore = kv_store_path((nArg>1)? azArg[1] : 0, ptu); + char *zStore = kv_store_path((nArg>1)? azArg[1] : 0, ptu); if( zStore==0 ){ utf8_printf(STD_ERR, "Cannot form parameter load path. Nothing loaded.\n"); return DCR_Error; }else{ const char **pzFirst = (nArg>2)? azArg+2 : 0; int nNames = (nArg>2)? nArg-2 : 0; - int rc = kv_xfr_table(db, zStore, 0, ptu, pzFirst, nNames); - if( nArg>1 && zStore!=azArg[1] ) sqlite3_free((void*)zStore); + int rc; + sstr_holder(zStore); + rc = kv_xfr_table(db, zStore, 0, ptu, pzFirst, nNames); + release_holder(); return rc; } } @@ -11759,15 +11782,17 @@ static int kv_pairs_load(sqlite3 *db, ParamTableUse ptu, /* Save some or all parameters. Arguments are "save FILE ?NAMES?". */ static int kv_pairs_save(sqlite3 *db, ParamTableUse ptu, const char *azArg[], int nArg){ - const char *zStore = kv_store_path((nArg>1)? azArg[1] : 0, ptu); + char *zStore = kv_store_path((nArg>1)? azArg[1] : 0, ptu); if( zStore==0 ){ utf8_printf(STD_ERR, "Cannot form parameter save path. Nothing saved.\n"); return DCR_Error; }else{ const char **pzFirst = (nArg>2)? azArg+2 : 0; int nNames = (nArg>2)? nArg-2 : 0; - int rc = kv_xfr_table(db, zStore, 1, ptu, pzFirst, nNames); - if( nArg>1 && zStore!=azArg[1] ) sqlite3_free((void*)zStore); + int rc; + sstr_holder(zStore); + rc = kv_xfr_table(db, zStore, 1, ptu, pzFirst, nNames); + release_holder(); return rc; } } @@ -11796,17 +11821,21 @@ static int edit_one_kvalue(sqlite3 *db, char *name, int eval, zSql = smprintf("SELECT value, uses FROM %s " "WHERE key=%Q AND uses=%d", zTab, name, uses); shell_check_ooms(zSql); - sqlite3_exec(db, zSql, kv_find_callback, &kvRow, 0); - sqlite3_free(zSql); + sstr_ptr_holder(&kvRow.value); + sstr_holder(zSql); + shell_check_nomem(sqlite3_exec(db, zSql, kv_find_callback, &kvRow, 0)); + release_holder(); assert(kvRow.hits<2); if( kvRow.hits==1 && kvRow.uses==uses){ /* Editing an existing value of same kind. */ - sqlite3_free(kvRow.value); + release_holder(); /* kvRow.value */ if( eval!=0 ){ zSql = smprintf("SELECT edit(value, %Q) FROM %s " "WHERE key=%Q AND uses=%d", zEditor, zTab, name, uses); shell_check_ooms(zSql); + sstr_holder(zSql); zVal = db_text(db, zSql, 1); + release_holder(); sqlite3_free(zSql); zSql = smprintf("UPDATE %s SET value=(SELECT %s) " "WHERE key=%Q AND uses=%d", zTab, zVal, name, uses); @@ -11817,10 +11846,12 @@ static int edit_one_kvalue(sqlite3 *db, char *name, int eval, }else{ /* Editing a new value of same kind. */ assert(kvRow.value==0 || kvRow.uses!=uses); + drop_holder(); /* kvRow.value */ if( eval!=0 ){ zSql = smprintf("SELECT edit('-- %q%s', %Q)", name, "\n", zEditor); + sstr_holder(zSql); zVal = db_text(db, zSql, 1); - sqlite3_free(zSql); + release_holder(); zSql = smprintf("INSERT INTO %s(key,value,uses)" " VALUES (%Q,(SELECT %s LIMIT 1),%d)", zTab, name, zVal, uses); @@ -11831,9 +11862,10 @@ static int edit_one_kvalue(sqlite3 *db, char *name, int eval, } } shell_check_ooms(zSql); + sstr_holder(zSql); + sstr_holder(zVal); rc = sqlite3_exec(db, zSql, 0, 0, 0); - sqlite3_free(zSql); - sqlite3_free(zVal); + release_holders(2); return rc!=SQLITE_OK; } #endif @@ -11888,12 +11920,14 @@ static int shvar_set(sqlite3 *db, char *name, char **valBeg, char **valLim){ = smprintf("REPLACE INTO "SHVAR_TABLE_SNAME"(key,value,uses)" "VALUES(%Q,%Q,"SPTU_Script");", name, zValue); shell_check_ooms(zSql); - rc = sqlite3_prepare_v2(db, zSql, -1, &pStmtSet, 0); + sstr_holder(zValGlom); + sstr_holder(zSql); + rc = shell_check_nomem(sqlite3_prepare_v2(db, zSql, -1, &pStmtSet, 0)); assert(rc==SQLITE_OK); - sqlite3_free(zSql); - rc = (SQLITE_DONE==sqlite3_step(pStmtSet))? SQLITE_OK : SQLITE_ERROR; - sqlite3_finalize(pStmtSet); - sqlite3_free(zValGlom); + stmt_holder(pStmtSet); + rc = shell_check_nomem(sqlite3_step(pStmtSet)); + rc = (SQLITE_DONE==rc)? SQLITE_OK : SQLITE_ERROR; + release_holders(3); return rc; } @@ -16810,11 +16844,11 @@ int SQLITE_CDECL SHELL_MAIN(int argc, wchar_t **wargv){ sstr_holder(z); n = strlen(z); argsUtf8.azCmd[i] = malloc( n+1 ); - if( argsUtf8.azCmd[i] ) ++argsUtf8.nCmd; - else shell_out_of_memory(); - sqlite3_free(pop_holder()); - --main_resource_mark; + shell_check_oomm(argsUtf8.azCmd[i]); + ++argsUtf8.nCmd; memcpy(argsUtf8.azCmd[i], z, n+1); + release_holder(); + --main_resource_mark; } sqlite3_shutdown(); argv = argsUtf8.azCmd;