Enhancements to shell_prompt_test() for better testing. Enhance the

".open" command so that it does ~/ expansion on filenames.

FossilOrigin-Name: ec6830fe60b73bc606d3c2a5d407a39db53f6dadee760829410abfa1df46389e
This commit is contained in:
drh
2026-04-11 14:11:56 +00:00
parent cd28797117
commit fc2c730c87
3 changed files with 104 additions and 30 deletions
+6 -6
View File
@@ -1,5 +1,5 @@
C Remove\sarbitrary\slimits\son\sthe\slength\sof\sCLI\sprompts.\s\sUse\senvironment\nvariables\sSQLITE_PS1\sand\sSQLITE_PS2\s(if\sthey\sexist)\sas\sthe\sdefault\nCLI\sprompts.
D 2026-04-11T12:35:53.197
C Enhancements\sto\sshell_prompt_test()\sfor\sbetter\stesting.\s\sEnhance\sthe\n".open"\scommand\sso\sthat\sit\sdoes\s~/\sexpansion\son\sfilenames.
D 2026-04-11T14:11:56.053
F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
@@ -735,7 +735,7 @@ F src/random.c 606b00941a1d7dd09c381d3279a058d771f406c5213c9932bbd93d5587be4b9c
F src/resolve.c 928ff887f2a7c64275182060d94d06fdddbe32226c569781cf7e7edc6f58d7fd
F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97
F src/select.c ffe199f025a0dd74670d2a77232bdea364a4d7b36f32c64a6572d39ba6a11576
F src/shell.c.in 7ad3effc35e738c90d87b6b5336a0ddd7cc1bcb32cfc7c73cab4666e8c0afb22
F src/shell.c.in 7145f12e0a923fca7f1716086796e279785d19d95dfaa3ac7314e59e29d086c0
F src/sqlite.h.in a5605faa9479bbaac16c4ab43eb09ff50632004a8e05084d3fde56063ef73766
F src/sqlite3.rc 015537e6ac1eec6c7050e17b616c2ffe6f70fca241835a84a4f0d5937383c479
F src/sqlite3ext.h 1b7a0ee438bb5c2896d0609c537e917d8057b3340f6ad004d2de44f03e3d3cca
@@ -2197,8 +2197,8 @@ F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee
F tool/warnings.sh a554d13f6e5cf3760f041b87939e3d616ec6961859c3245e8ef701d1eafc2ca2
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
F tool/winmain.c 00c8fb88e365c9017db14c73d3c78af62194d9644feaf60e220ab0f411f3604c
P c6ff4f701d9cf963cf2472ed72ad4e201227560dde2ba8d48602af2e49170e89
R 5b11b0f858f42d7a9b800b9821aa8115
P a46ceaeab968d8f376c5a225c23c0be8619fed4511b7e567baf3a8d7736c19d1
R b145f37224b01e5b0236a04795b472a6
U drh
Z c8ef1c46f1e4fc036ec422f313143d28
Z 7ccada63678abda6f630b8ea89fca70f
# Remove this line to create a well-formed Fossil manifest.
+1 -1
View File
@@ -1 +1 @@
a46ceaeab968d8f376c5a225c23c0be8619fed4511b7e567baf3a8d7736c19d1
ec6830fe60b73bc606d3c2a5d407a39db53f6dadee760829410abfa1df46389e
+97 -23
View File
@@ -410,6 +410,7 @@ struct ShellState {
sqlite3 *db; /* Connection pointer */
const char *zDbFilename; /* Filename used to open the connection */
char *zFreeOnClose; /* Free this memory allocation on close */
int mFlgs; /* 0x001: Use zDbFilenaem for prompt */
#if defined(SQLITE_ENABLE_SESSION)
int nSession; /* Number of active sessions */
OpenSession aSession[4]; /* Array of sessions. [0] is in focus. */
@@ -934,6 +935,24 @@ static const char *prompt_string(ShellState *p, int bContinue){
}
}
/*
** Return the name of the open database file, to be used for prompt
** expansion purposes.
*/
static const char *prompt_filename(ShellState *p){
sqlite3_filename pFN;
const char *zFN = 0;
if( p->pAuxDb->mFlgs & 0x01 ){
zFN = p->pAuxDb->zDbFilename;
}else if( p->db && (pFN = sqlite3_db_filename(p->db,0))!=0 ){
zFN = sqlite3_filename_database(pFN);
}
if( zFN==0 || zFN[0]==0 ){
zFN = "in-memory";
}
return zFN;
}
/*
** Expand escapes in the given input prompt string. Return the
** expanded prompt in memory obtained from sqlite3_malloc(). The
@@ -1027,27 +1046,23 @@ static char *expand_prompt(
/* \F becomes the full pathname */
/* \~ becomes the full pathname relative to $HOME */
if( onoff ){
sqlite3_filename pFN = p->db ? sqlite3_db_filename(p->db,0) : 0;
const char *zFN = pFN ? sqlite3_filename_database(pFN) : "";
if( zFN ){
if( zFN[0]==0 ) zFN = "in-memory";
if( c=='f' ){
const char *zFN = prompt_filename(p);
if( c=='f' ){
#ifdef _WIN32
const char *zTail = strrchr(zFN,'\\');
const char *zTail = strrchr(zFN,'\\');
#else
const char *zTail = strrchr(zFN,'/');
const char *zTail = strrchr(zFN,'/');
#endif
if( zTail && zTail[1] ) zFN = &zTail[1];
}else if( c=='~' ){
const char *zHOME = getenv("HOME");
size_t nHOME = zHOME ? strlen(zHOME) : 0;
if( nHOME<strlen(zFN) && memcmp(zHOME,zFN,nHOME)==0 ){
sqlite3_str_append(pOut,"~",1);
zFN += nHOME;
}
if( zTail && zTail[1] ) zFN = &zTail[1];
}else if( c=='~' ){
const char *zHOME = getenv("HOME");
size_t nHOME = zHOME ? strlen(zHOME) : 0;
if( nHOME<strlen(zFN) && memcmp(zHOME,zFN,nHOME)==0 ){
sqlite3_str_append(pOut,"~",1);
zFN += nHOME;
}
sqlite3_str_appendall(pOut, zFN);
}
sqlite3_str_appendall(pOut, zFN);
}
zPrompt += 2;
i = -1;
@@ -1499,19 +1514,50 @@ static void shellAddSchemaName(
}
/*
** SQL function: shell_expand_prompt(PROMPT,PRIOR)
** SQL function: shell_prompt_test(PROMPT)
** shell_prompt_test(PROMPT,PRIOR)
** shell_prompt_test(PROMPT,PRIOR,FILENAME)
**
** Invoke the internal expand_prompt() function, for testing purposes.
** Return the shell prompt, with escapes expanded, for testing purposes.
** The first argument is the raw (unexpanded) prompt string. Or if the
** first argument is NULL, then use whatever prompt string is currently
** configured. If the second argument exists and is not NULL, then the
** second argument is understood to be prior incomplete text and a
** continuation prompt is generated. If a third argument is provided,
** it is assumed to be the full pathname of the database file.
*/
static void shellExpandPrompt(
sqlite3_context *pCtx,
int nVal,
sqlite3_value **apVal
){
const char *zPrompt = (const char*)sqlite3_value_text(apVal[0]);
const char *zPrior = nVal>=2 ? (const char*)sqlite3_value_text(apVal[1]) : 0;
ShellState *p = (ShellState*)sqlite3_user_data(pCtx);
char *zRes = expand_prompt(p, zPrior, zPrompt);
const char *zPrompt;
const char *zPrior;
const char *zSavedDbFile;
int mSavedFlgs;
const char *zFName;
char *zRes;
if( nVal<2
|| (zPrior = (const char*)sqlite3_value_text(apVal[1]))==0
|| zPrior[0]==0
){
zPrior = 0;
}
zPrompt = (const char*)sqlite3_value_text(apVal[0]);
if( zPrompt==0 ){
zPrompt = prompt_string(p, zPrior!=0);
}
zSavedDbFile = p->pAuxDb->zDbFilename;
mSavedFlgs = p->pAuxDb->mFlgs;
if( nVal>=3 && (zFName = (const char*)sqlite3_value_text(apVal[2]))!=0 ){
p->pAuxDb->zDbFilename = zFName;
p->pAuxDb->mFlgs |= 0x001;
}
zRes = expand_prompt(p, zPrior, zPrompt);
p->pAuxDb->zDbFilename = zSavedDbFile;
p->pAuxDb->mFlgs = mSavedFlgs;
sqlite3_result_text(pCtx, zRes, -1, SQLITE_TRANSIENT);
sqlite3_free(zRes);
}
@@ -4604,6 +4650,31 @@ static void shellModuleSchema(
static void open_db(ShellState *p, int openFlags){
if( p->db==0 ){
const char *zDbFilename = p->pAuxDb->zDbFilename;
const char *zHOME; /* Value of HOME environment variable */
char *zToFree = 0; /* Filename with ~/ prefix expansion */
/* If the zDbFilename does not exist and begins with ~/ then replace
** the ~ with the home directory.
*/
if( zDbFilename && zDbFilename[0]=='~'
#ifdef _WIN32
&& (zDbFilename[1]=='/' || zDbFilename[1]=='\\')
#else
&& zDbFilename[1]=='/'
#endif
&& access(zDbFilename,0)!=0
&& (zHOME = getenv("HOME"))!=0 && zHOME[0]!=0
){
size_t nHOME = strlen(zHOME);
size_t nFN = strlen(zDbFilename);
zToFree = malloc(nHOME+nFN+1);
if( zToFree ){
memcpy(zToFree, zHOME, nHOME);
memcpy(zToFree+nHOME, zDbFilename+1, nFN);
zDbFilename = zToFree;
}
}
if( p->openMode==SHELL_OPEN_UNSPEC ){
if( zDbFilename==0 || zDbFilename[0]==0 ){
p->openMode = SHELL_OPEN_NORMAL;
@@ -4737,9 +4808,11 @@ static void open_db(ShellState *p, int openFlags){
sqlite3_create_function(p->db, "edit", 2, SQLITE_UTF8, 0,
editFunc, 0, 0);
#endif
sqlite3_create_function(p->db, "shell_expand_prompt", 1, SQLITE_UTF8,
sqlite3_create_function(p->db, "shell_prompt_test", 1, SQLITE_UTF8,
p, shellExpandPrompt, 0, 0);
sqlite3_create_function(p->db, "shell_expand_prompt", 2, SQLITE_UTF8,
sqlite3_create_function(p->db, "shell_prompt_test", 2, SQLITE_UTF8,
p, shellExpandPrompt, 0, 0);
sqlite3_create_function(p->db, "shell_prompt_test", 3, SQLITE_UTF8,
p, shellExpandPrompt, 0, 0);
@@ -4775,6 +4848,7 @@ static void open_db(ShellState *p, int openFlags){
}
}
#endif
free(zToFree);
}
if( p->db!=0 ){
#ifndef SQLITE_OMIT_AUTHORIZATION