-C Fix\sharmless\scompiler\swarning.
-D 2026-04-23T14:49:21.443
+C New\sCLI\sprompt\sescape\ssequences:\s\s/r,\s/A,\s/v,\s/V,\sand\s/D../D.
+D 2026-04-23T15:05:46.973
F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
F src/resolve.c 928ff887f2a7c64275182060d94d06fdddbe32226c569781cf7e7edc6f58d7fd
F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97
F src/select.c 4c05cde130f26991b7411d8c6809e0630625e18078742c963a047b4b9cc01d49
-F src/shell.c.in 20e359ac77d07e5dc636e526ef85da692384228e7997d7ec28568125a028a8f7
+F src/shell.c.in ae78db9539da5f8ada1ac2761b77b865e56ec2ba9145461e56de6eb762aeef18
F src/sqlite.h.in 39d2e09114d2bdb7afd998f4a469c8f8cd065f8093835a7d0422f260fc78fb4f
F src/sqlite3.rc 015537e6ac1eec6c7050e17b616c2ffe6f70fca241835a84a4f0d5937383c479
F src/sqlite3ext.h 9788c301f95370fa30e808861f1d2e6f022a816ddbe2a4f67486784c1b31db2e
F test/sharedB.test 1a84863d7a2204e0d42f2e1606577c5e92e4473fa37ea0f5bdf829e4bf8ee707
F test/shared_err.test 32634e404a3317eeb94abc7a099c556a346fdb8fb3858dbe222a4cbb8926a939
F test/sharedlock.test 5ede3c37439067c43b0198f580fd374ebf15d304
-F test/shell-prompt.sql 43ed98433bfde83171b5d06c300525154f4cab9230570a326ca606aaef351db6
+F test/shell-prompt.sql c3517832b8570025619707bf5883847f6894e958bd92a5e0d2e2f157f768c2a1
F test/shell1.test c84eff209f93ad17ccdf7e1634969fc8231684254edeb21d9b13d67c3179cdb5
F test/shell2.test dc541d2681503e55466a24d35a4cbf8ca5b90b8fcdef37fc4db07373a67d31d3
F test/shell3.test 91efdd545097a61a1f72cf79c9ad5b49da080f3f10282eaf4c3c272cd1012db2
F tool/warnings.sh a554d13f6e5cf3760f041b87939e3d616ec6961859c3245e8ef701d1eafc2ca2
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
F tool/winmain.c 00c8fb88e365c9017db14c73d3c78af62194d9644feaf60e220ab0f411f3604c
-P 3fa0500b964869c45f7b49717680b791049f7cd8c47a06a337dd22351d2002f9
-R 71b891a74b506696ae0597a74a57a86c
+P 706373dcbe43752cf21604f278f96fb3015a36089ad64f069bb3a64bc526d137
+R d97f1546f6e3e8815d53cf5cfb6143b0
U drh
-Z 6b30685bdb9a615afb7f74468ca1c1e4
+Z b0844759ca50f5075fba7f38fd3b6ac9
# Remove this line to create a well-formed Fossil manifest.
** The default prompts.
*/
#ifndef SQLITE_PS1
-# define SQLITE_PS1 "SQLite /f> "
+# define SQLITE_PS1 "/A /f> "
#endif
#ifndef SQLITE_PS2
# define SQLITE_PS2 "/B.../H> "
#endif
+/*
+** Redefinable escape value for the prompt string.
+*/
+#ifndef SQLITE_PS_APP
+# define SQLITE_PS_APP "SQLite" /* Expansion for /A */
+#endif
+#ifndef SQLITE_PS_RELEASE
+# define SQLITE_PS_VERSION_RELEASE shellRelease() /* Expansion for /v */
+#endif
+#ifndef SQLITE_PS_PATCH
+# define SQLITE_PS_VERSION_PATCH shellPatch() /* Expansion for /V */
+#endif
+
/*
** Return the raw (unexpanded) prompt string. This will be the
** first of the following that exist:
return zFN;
}
+/*
+** Return strings appropriate to substitute for /V and /v
+*/
+static const char *shellPatch(void){ return sqlite3_libversion(); }
+static const char *shellRelease(void){
+ static char zRel[16];
+ const char *zF = shellPatch();
+ const char *zD = strrchr(zF,'.');
+ int i = (int)(zD - zF);
+ memcpy(zRel,zF,i);
+ zRel[i] = 0;
+ return zRel;
+}
+
/*
** Expand escapes in the given input prompt string. Return the
** expanded prompt in memory obtained from sqlite3_malloc(). The
sqlite3_str *pOut = sqlite3_str_new(0);
int i;
char c;
- int onoff = 1;
+ unsigned int mOff = 0; /* Bitmask of FALSE for if/then/else */
int idxSpace = -1;
+ int iDate = -1;
for(i=0; zPrompt[i]; i++){
if( zPrompt[i]!='/' ) continue;
if( i>0 ){
- if( onoff ) sqlite3_str_append(pOut, zPrompt, i);
+ if( !mOff ) sqlite3_str_append(pOut, zPrompt, i);
zPrompt += i;
i = 0;
}
while( i<=2 && zPrompt[i+1]>='0' && zPrompt[i+1]<='7' ){
v = v*8 + zPrompt[++i] - '0';
}
- if( onoff ) sqlite3_str_appendchar(pOut, 1, v);
+ if( !mOff ) sqlite3_str_appendchar(pOut, 1, v);
zPrompt += i+1;
i = -1;
continue;
}
if( c=='e' ){
/* /e is shorthand for /033 which is U+001B "Escape" */
- if( onoff ) sqlite3_str_append(pOut, "\033", 1);
+ if( !mOff ) sqlite3_str_append(pOut, "\033", 1);
+ zPrompt += 2;
+ i = -1;
+ continue;
+ }
+ if( c=='A' ){
+ /* /A expands to the application name */
+ if( !mOff ) sqlite3_str_appendall(pOut, SQLITE_PS_APP);
+ zPrompt += 2;
+ i = -1;
+ continue;
+ }
+ if( c=='V' ){
+ /* /V expands to the version number with patch level */
+ if( !mOff ) sqlite3_str_appendall(pOut, SQLITE_PS_VERSION_PATCH);
+ zPrompt += 2;
+ i = -1;
+ continue;
+ }
+ if( c=='v' ){
+ /* /v expands to the version number without the patch level */
+ /* /V expands to the version number with patch level */
+ if( !mOff ) sqlite3_str_appendall(pOut, SQLITE_PS_VERSION_RELEASE);
zPrompt += 2;
i = -1;
continue;
** .prompt '/e[1;/x31/:34/;m~f>/e[0m '
*/
if( c==':' ){
- /* toggle display on/off */
- onoff = !onoff;
+ /* ELSE: toggle display on/off */
+ mOff ^= 1;
zPrompt += 2;
i = -1;
continue;
}
if( c==';' ){
- /* Turn display on */
- onoff = 1;
+ /* ENDIF: Turn display on */
+ mOff >>= 1;
zPrompt += 2;
i = -1;
continue;
}
if( c=='x' ){
/* /x turns display off not in a transaction, on if in txn */
- onoff = p->db && !sqlite3_get_autocommit(p->db);
+ mOff = (mOff<<1) | (p->db==0 || sqlite3_get_autocommit(p->db)!=0);
+ zPrompt += 2;
+ i = -1;
+ continue;
+ }
+ if( c=='r' ){
+ /* /r turns display off if database is read/write, on if read-only */
+ mOff = (mOff<<1) | (p->db==0 || sqlite3_db_readonly(p->db,0)==0);
zPrompt += 2;
i = -1;
continue;
/* /f becomes the tail of the database filename */
/* /F becomes the full pathname */
/* /~ becomes the full pathname relative to $HOME */
- if( onoff ){
+ if( !mOff ){
const char *zFN = prompt_filename(p);
if( c=='f' ){
#ifdef _WIN32
if( c=='H' ){
/* /H becomes text needed to terminate current input */
- if( onoff ){
+ if( !mOff ){
sqlite3_int64 R = zPrior ? sqlite3_incomplete(zPrior) : 0;
int cc = (R>>16)&0xff;
int nParen = R>>32;
/* /B is a no-op for the main prompt. For the continuation prompt,
** /B expands to zero or more spaces to make the continuation prompt
** at least as wide as the main prompt. */
- if( onoff ) idxSpace = sqlite3_str_length(pOut);
+ if( !mOff ) idxSpace = sqlite3_str_length(pOut);
+ zPrompt += 2;
+ i = -1;
+ continue;
+ }
+
+ if( c=='D' ){
+ /* /D.../D replaces all of the text between the two /D escapes with
+ ** the result from strftime(). */
+ if( iDate<0 ){
+ iDate = sqlite3_str_length(pOut);
+ }else{
+ if( !mOff ){
+ time_t now;
+ char zBuf[200];
+ zBuf[0] = 0;
+ time(&now);
+ strftime(zBuf, sizeof(zBuf)-1, sqlite3_str_value(pOut)+iDate,
+ localtime(&now));
+ zBuf[199] = 0;
+ sqlite3_str_truncate(pOut, iDate);
+ sqlite3_str_appendall(pOut, zBuf);
+ }
+ iDate = -1;
+ }
zPrompt += 2;
i = -1;
continue;
}
- /* No match to a known escape. Generate an error. */
- if( onoff ) sqlite3_str_appendf(pOut,"UNKNOWN(\"/%c\")",c);
+ /* No match to a known escape. Generate an error. The mOff flag
+ ** is ignored for this output, so that errors appear even if they
+ ** are in an unused branch. */
+ sqlite3_str_appendf(pOut,"UNKNOWN(\"/%c\")",c);
zPrompt += 2;
i = -1;
}
- if( i>0 && onoff ){
+ if( i>0 && !mOff ){
sqlite3_str_append(pOut, zPrompt, i);
}