aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/shell.c.in104
-rw-r--r--src/sqliteInt.h2
-rw-r--r--src/vdbe.h2
-rw-r--r--src/vdbeaux.c2
-rw-r--r--src/whereexpr.c2
5 files changed, 70 insertions, 42 deletions
diff --git a/src/shell.c.in b/src/shell.c.in
index 5cda6a1a1..a311d85c4 100644
--- a/src/shell.c.in
+++ b/src/shell.c.in
@@ -12760,59 +12760,79 @@ static char *find_home_dir(int clearFlag){
}
/*
-** On non-Windows platforms, look for $XDG_CONFIG_HOME.
-** If ${XDG_CONFIG_HOME}/sqlite3/sqliterc is found, return
-** the path to it. If there is no $(XDG_CONFIG_HOME) then
-** look for $(HOME)/.config/sqlite3/sqliterc and if found
-** return that. If none of these are found, return 0.
+** On non-Windows platforms, look for:
**
-** The string returned is obtained from sqlite3_malloc() and
-** should be freed by the caller.
+** - ${zEnvVar}/${zBaseName}
+** - ${HOME}/${zSubdir}/${zBaseName}
+**
+** $zEnvVar is intended to be the name of an XDG_... environment
+** variable, e.g. XDG_CONFIG_HOME or XDG_STATE_HOME. If zEnvVar is
+** NULL or getenv(zEnvVar) is NULL then fall back to the second
+** option. If the selected option is not found in the filesystem,
+** return 0.
+**
+** zSubdir may be NULL or empty, in which case ${HOME}/${zBaseName}
+** becomes the fallback.
+**
+** Both zSubdir and zBaseName may contain subdirectory parts. zSubdir
+** will conventionally be ".config" or ".local/state", which, not
+** coincidentally, is the typical subdir of the corresponding XDG_...
+** var with the XDG var's $HOME prefix.
+**
+** The returned string is obtained from sqlite3_malloc() and should be
+** sqlite3_free()'d by the caller.
*/
-static char *find_xdg_config(void){
+static char *find_xdg_file(const char *zEnvVar, const char *zSubdir,
+ const char *zBaseName){
#if defined(_WIN32) || defined(WIN32) || defined(_WIN32_WCE) \
|| defined(__RTP__) || defined(_WRS_KERNEL)
return 0;
#else
- char *zConfig = 0;
- const char *zXdgHome;
+ char *zConfigFile = 0;
+ const char *zXdgDir;
- zXdgHome = getenv("XDG_CONFIG_HOME");
- if( zXdgHome==0 ){
- const char *zHome = getenv("HOME");
- if( zHome==0 ) return 0;
- zConfig = sqlite3_mprintf("%s/.config/sqlite3/sqliterc", zHome);
+ zXdgDir = zEnvVar ? getenv(zEnvVar) : 0;
+ if( zXdgDir ){
+ zConfigFile = sqlite3_mprintf("%s/%s", zXdgDir, zBaseName);
}else{
- zConfig = sqlite3_mprintf("%s/sqlite3/sqliterc", zXdgHome);
+ const char * zHome = find_home_dir(0);
+ if( zHome==0 ) return 0;
+ zConfigFile = (zSubdir && *zSubdir)
+ ? sqlite3_mprintf("%s/%s/%s", zHome, zSubdir, zBaseName)
+ : sqlite3_mprintf("%s/%s", zHome, zBaseName);
}
- shell_check_oom(zConfig);
- if( access(zConfig,0)!=0 ){
- sqlite3_free(zConfig);
- zConfig = 0;
+ shell_check_oom(zConfigFile);
+ if( access(zConfigFile,0)!=0 ){
+ sqlite3_free(zConfigFile);
+ zConfigFile = 0;
}
- return zConfig;
+ return zConfigFile;
#endif
}
/*
-** Read input from the file given by sqliterc_override. Or if that
-** parameter is NULL, take input from the first of find_xdg_config()
-** or ~/.sqliterc which is found.
+** Read input from the file sqliterc_override. If that parameter is
+** NULL, take it from find_xdg_file(), if found, or fall back to
+** ~/.sqliterc.
**
-** Returns the number of errors.
+** Failure to read the config is only considered a failure if
+** sqliterc_override is not NULL, in which case this function may emit
+** a warning or, if ::bail_on_error is true, fail fatally if the file
+** named by sqliterc_override is not found.
*/
static void process_sqliterc(
ShellState *p, /* Configuration data */
const char *sqliterc_override /* Name of config file. NULL to use default */
){
char *home_dir = NULL;
- const char *sqliterc = sqliterc_override;
- char *zBuf = 0;
+ char *sqliterc = (char*)sqliterc_override;
FILE *inSaved = p->in;
int savedLineno = p->lineno;
if( sqliterc == NULL ){
- sqliterc = zBuf = find_xdg_config();
+ sqliterc = find_xdg_file("XDG_CONFIG_HOME",
+ ".config",
+ "sqlite3/sqliterc");
}
if( sqliterc == NULL ){
home_dir = find_home_dir(0);
@@ -12821,11 +12841,10 @@ static void process_sqliterc(
" cannot read ~/.sqliterc\n");
return;
}
- zBuf = sqlite3_mprintf("%s/.sqliterc",home_dir);
- shell_check_oom(zBuf);
- sqliterc = zBuf;
+ sqliterc = sqlite3_mprintf("%s/.sqliterc",home_dir);
+ shell_check_oom(sqliterc);
}
- p->in = sqlite3_fopen(sqliterc,"rb");
+ p->in = sqliterc ? sqlite3_fopen(sqliterc,"rb") : 0;
if( p->in ){
if( stdin_is_interactive ){
sqlite3_fprintf(stderr,"-- Loading resources from %s\n", sqliterc);
@@ -12838,7 +12857,9 @@ static void process_sqliterc(
}
p->in = inSaved;
p->lineno = savedLineno;
- sqlite3_free(zBuf);
+ if( sqliterc != sqliterc_override ){
+ sqlite3_free(sqliterc);
+ }
}
/*
@@ -13606,7 +13627,6 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){
if( stdin_is_interactive ){
char *zHome;
char *zHistory;
- int nHistory;
sqlite3_fprintf(stdout,
"SQLite version %s %.19s\n" /*extra-version-info*/
"Enter \".help\" for usage hints.\n",
@@ -13619,11 +13639,15 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){
}
zHistory = getenv("SQLITE_HISTORY");
if( zHistory ){
- zHistory = strdup(zHistory);
- }else if( (zHome = find_home_dir(0))!=0 ){
- nHistory = strlen30(zHome) + 20;
- if( (zHistory = malloc(nHistory))!=0 ){
- sqlite3_snprintf(nHistory, zHistory,"%s/.sqlite_history", zHome);
+ zHistory = sqlite3_mprintf("%s", zHistory);
+ shell_check_oom(zHistory);
+ }else{
+ zHistory = find_xdg_file("XDG_STATE_HOME",
+ ".local/state",
+ "sqlite_history");
+ if( 0==zHistory && (zHome = find_home_dir(0))!=0 ){
+ zHistory = sqlite3_mprintf("%s/.sqlite_history", zHome);
+ shell_check_oom(zHistory);
}
}
if( zHistory ){ shell_read_history(zHistory); }
@@ -13639,7 +13663,7 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){
if( zHistory ){
shell_stifle_history(2000);
shell_write_history(zHistory);
- free(zHistory);
+ sqlite3_free(zHistory);
}
}else{
data.in = stdin;
diff --git a/src/sqliteInt.h b/src/sqliteInt.h
index 7b914d958..df0e1c3ba 100644
--- a/src/sqliteInt.h
+++ b/src/sqliteInt.h
@@ -2166,7 +2166,7 @@ struct FuncDestructor {
#define STR_FUNCTION(zName, nArg, pArg, bNC, xFunc) \
{nArg, SQLITE_FUNC_BUILTIN|\
SQLITE_FUNC_SLOCHNG|SQLITE_UTF8|(bNC*SQLITE_FUNC_NEEDCOLL), \
- pArg, 0, xFunc, 0, 0, 0, #zName, }
+ pArg, 0, xFunc, 0, 0, 0, #zName, {0} }
#define LIKEFUNC(zName, nArg, arg, flags) \
{nArg, SQLITE_FUNC_BUILTIN|SQLITE_FUNC_CONSTANT|SQLITE_UTF8|flags, \
(void *)arg, 0, likeFunc, 0, 0, 0, #zName, {0} }
diff --git a/src/vdbe.h b/src/vdbe.h
index a7aedfbb0..9a9cf3dec 100644
--- a/src/vdbe.h
+++ b/src/vdbe.h
@@ -314,7 +314,9 @@ int sqlite3VdbeHasSubProgram(Vdbe*);
void sqlite3MemSetArrayInt64(sqlite3_value *aMem, int iIdx, i64 val);
+#ifndef SQLITE_OMIT_DATETIME_FUNCS
int sqlite3NotPureFunc(sqlite3_context*);
+#endif
#ifdef SQLITE_ENABLE_BYTECODE_VTAB
int sqlite3VdbeBytecodeVtabInit(sqlite3*);
#endif
diff --git a/src/vdbeaux.c b/src/vdbeaux.c
index 8a900aeff..b1406724e 100644
--- a/src/vdbeaux.c
+++ b/src/vdbeaux.c
@@ -5378,6 +5378,7 @@ void sqlite3VdbeSetVarmask(Vdbe *v, int iVar){
}
}
+#ifndef SQLITE_OMIT_DATETIME_FUNCS
/*
** Cause a function to throw an error if it was call from OP_PureFunc
** rather than OP_Function.
@@ -5411,6 +5412,7 @@ int sqlite3NotPureFunc(sqlite3_context *pCtx){
}
return 1;
}
+#endif /* SQLITE_OMIT_DATETIME_FUNCS */
#if defined(SQLITE_ENABLE_CURSOR_HINTS) && defined(SQLITE_DEBUG)
/*
diff --git a/src/whereexpr.c b/src/whereexpr.c
index e9fa4a143..0d17b0d75 100644
--- a/src/whereexpr.c
+++ b/src/whereexpr.c
@@ -1541,7 +1541,7 @@ static void exprAnalyze(
idxNew = whereClauseInsert(pWC, pNewExpr, TERM_VIRTUAL|TERM_DYNAMIC);
testcase( idxNew==0 );
pNewTerm = &pWC->a[idxNew];
- pNewTerm->prereqRight = prereqExpr;
+ pNewTerm->prereqRight = prereqExpr | extraRight;
pNewTerm->leftCursor = pLeft->iTable;
pNewTerm->u.x.leftColumn = pLeft->iColumn;
pNewTerm->eOperator = WO_AUX;