]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Enhancements to shell_prompt_test() for better testing. Enhance the
authordrh <>
Sat, 11 Apr 2026 14:11:56 +0000 (14:11 +0000)
committerdrh <>
Sat, 11 Apr 2026 14:11:56 +0000 (14:11 +0000)
".open" command so that it does ~/ expansion on filenames.

FossilOrigin-Name: ec6830fe60b73bc606d3c2a5d407a39db53f6dadee760829410abfa1df46389e

manifest
manifest.uuid
src/shell.c.in

index 5e3013e532281c36e0953e22bf970ff22a000ad2..9bdd902a79c0846fd7065aa58eb1a219bf27d57d 100644 (file)
--- a/manifest
+++ b/manifest
@@ -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.
index 734582b578944a2582f210c23f8937ab7ab81279..f91f7fa9a957d09a14635c9457010b5bd34f9325 100644 (file)
@@ -1 +1 @@
-a46ceaeab968d8f376c5a225c23c0be8619fed4511b7e567baf3a8d7736c19d1
+ec6830fe60b73bc606d3c2a5d407a39db53f6dadee760829410abfa1df46389e
index 9db31bcf37a75db7f0b3dabd385eb27ccddb39f9..89b3f47e344bdbcdc97b8db2fcee2460d988b1b4 100644 (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,'/');
-#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;
-            }
+          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;
           }
-          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_prompt_test", 2, 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", 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