mirror of
https://github.com/sqlite/sqlite.git
synced 2026-10-23 21:49:02 +03:00
Strip out the legacy dynamic prompt generation. It will go back in as I
add the user-defined prompt escapes. FossilOrigin-Name: ab08b7a8ef518f96a549a41fe8ff11776abe5e83153c5f8d5d58694ecc476389
This commit is contained in:
15
manifest
15
manifest
@@ -1,5 +1,5 @@
|
||||
C Clean-ups\sin\sprompt\sgeneration\sin\sthe\sCLI.
|
||||
D 2026-04-09T18:51:09.198
|
||||
C Strip\sout\sthe\slegacy\sdynamic\sprompt\sgeneration.\s\sIt\swill\sgo\sback\sin\sas\sI\nadd\sthe\suser-defined\sprompt\sescapes.
|
||||
D 2026-04-09T20:21:25.880
|
||||
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 1dcccee78238e27dfa90df67e15fb194c087f552608248fd900b7a5ee730782a
|
||||
F src/shell.c.in d2d6accf85d516d39ffb5101e3209e22b062c014be0b7c467c12bc3d2e9a4f96
|
||||
F src/sqlite.h.in e2915e4a86d5e0783afb5cb72411df38d987c7f3c5aa2d5441b8e74d30b649d8
|
||||
F src/sqlite3.rc 015537e6ac1eec6c7050e17b616c2ffe6f70fca241835a84a4f0d5937383c479
|
||||
F src/sqlite3ext.h 1b7a0ee438bb5c2896d0609c537e917d8057b3340f6ad004d2de44f03e3d3cca
|
||||
@@ -2197,8 +2197,11 @@ F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee
|
||||
F tool/warnings.sh a554d13f6e5cf3760f041b87939e3d616ec6961859c3245e8ef701d1eafc2ca2
|
||||
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
|
||||
F tool/winmain.c 00c8fb88e365c9017db14c73d3c78af62194d9644feaf60e220ab0f411f3604c
|
||||
P 8fd48b9fe47d47b3eca31d187f1d98174c257daea220ae7be18e4c82764d9d5c
|
||||
R 7ffb65d89e42eb90bf23dccbc7a1df3f
|
||||
P e2c9d4c6b731ea9afbb9cb22f86a3db3670ca67968f15891dc46ae1fc9ba34dc
|
||||
R 6a381ddbe79e14291b50a57316105ea7
|
||||
T *branch * cli-prompt-redo
|
||||
T *sym-cli-prompt-redo *
|
||||
T -sym-cli-prompt *
|
||||
U drh
|
||||
Z ee302bdc160a37743cf8ada2bf8fc7e4
|
||||
Z 400a2e048f10888511ab99293cd1badd
|
||||
# Remove this line to create a well-formed Fossil manifest.
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
branch cli-prompt
|
||||
tag cli-prompt
|
||||
branch cli-prompt-redo
|
||||
tag cli-prompt-redo
|
||||
|
||||
@@ -1 +1 @@
|
||||
e2c9d4c6b731ea9afbb9cb22f86a3db3670ca67968f15891dc46ae1fc9ba34dc
|
||||
ab08b7a8ef518f96a549a41fe8ff11776abe5e83153c5f8d5d58694ecc476389
|
||||
|
||||
261
src/shell.c.in
261
src/shell.c.in
@@ -811,102 +811,6 @@ static char *shell_strncpy(char *dest, const char *src, size_t n){
|
||||
return dest;
|
||||
}
|
||||
|
||||
/*
|
||||
** Optionally disable dynamic continuation prompt.
|
||||
** Unless disabled, the continuation prompt shows open SQL lexemes if any,
|
||||
** or open parentheses level if non-zero, or continuation prompt as set.
|
||||
** This facility interacts with the scanner and process_input() where the
|
||||
** below 5 macros are used.
|
||||
*/
|
||||
#ifdef SQLITE_OMIT_DYNAPROMPT
|
||||
# define CONTINUATION_PROMPT continuePrompt
|
||||
# define CONTINUE_PROMPT_RESET
|
||||
# define CONTINUE_PROMPT_AWAITS(p,s)
|
||||
# define CONTINUE_PROMPT_AWAITC(p,c)
|
||||
# define CONTINUE_PAREN_INCR(p,n)
|
||||
# define CONTINUE_PROMPT_PSTATE 0
|
||||
typedef void *t_NoDynaPrompt;
|
||||
# define SCAN_TRACKER_REFTYPE t_NoDynaPrompt
|
||||
#else
|
||||
# define CONTINUATION_PROMPT(X) dynamicContinuePrompt()
|
||||
# define CONTINUE_PROMPT_RESET(X) \
|
||||
do {setLexemeOpen(&dynPrompt,0,0); trackParenLevel(&dynPrompt,0);} while(0)
|
||||
# define CONTINUE_PROMPT_AWAITS(X,p,s) \
|
||||
if(p && stdin_is_interactive) setLexemeOpen(p, s, 0)
|
||||
# define CONTINUE_PROMPT_AWAITC(X,p,c) \
|
||||
if(p && stdin_is_interactive) setLexemeOpen(p, 0, c)
|
||||
# define CONTINUE_PAREN_INCR(X,p,n) \
|
||||
if(p && stdin_is_interactive) (trackParenLevel(p,n))
|
||||
# define CONTINUE_PROMPT_PSTATE(X) (&dynPrompt)
|
||||
typedef struct DynaPrompt *t_DynaPromptRef;
|
||||
# define SCAN_TRACKER_REFTYPE t_DynaPromptRef
|
||||
|
||||
static struct DynaPrompt {
|
||||
char dynamicPrompt[PROMPT_LEN_MAX];
|
||||
char acAwait[2];
|
||||
int inParenLevel;
|
||||
char *zScannerAwaits;
|
||||
} dynPrompt = { {0}, {0}, 0, 0 };
|
||||
|
||||
/* Record parenthesis nesting level change, or force level to 0. */
|
||||
static void trackParenLevel(struct DynaPrompt *p, int ni){
|
||||
p->inParenLevel += ni;
|
||||
if( ni==0 ) p->inParenLevel = 0;
|
||||
p->zScannerAwaits = 0;
|
||||
}
|
||||
|
||||
/* Record that a lexeme is opened, or closed with args==0. */
|
||||
static void setLexemeOpen(struct DynaPrompt *p, char *s, char c){
|
||||
if( s!=0 || c==0 ){
|
||||
p->zScannerAwaits = s;
|
||||
p->acAwait[0] = 0;
|
||||
}else{
|
||||
p->acAwait[0] = c;
|
||||
p->zScannerAwaits = p->acAwait;
|
||||
}
|
||||
}
|
||||
|
||||
/* Upon demand, derive the continuation prompt to display. */
|
||||
static char *dynamicContinuePrompt(void){
|
||||
int k; /* Number of context hint characters */
|
||||
int nSpace; /* Spaces at the start of continuePrompt */
|
||||
int nDot; /* Dots following spaces */
|
||||
int nOrig; /* Total size of continuePrompt in bytes */
|
||||
int nCore; /* nOrig + 1 - nSpace */
|
||||
|
||||
nOrig = (int)strlen(continuePrompt);
|
||||
if( nOrig<=1
|
||||
|| (dynPrompt.zScannerAwaits==0 && dynPrompt.inParenLevel == 0)
|
||||
){
|
||||
return continuePrompt;
|
||||
}
|
||||
for(nSpace=0; continuePrompt[nSpace]==' '; nSpace++){}
|
||||
for(nDot=0; continuePrompt[nSpace+nDot]=='.'; nDot++){}
|
||||
nCore = nOrig + 1 - nSpace;
|
||||
for(k=0; k<dynPrompt.inParenLevel && k+nCore<PROMPT_LEN_MAX; k++){
|
||||
dynPrompt.dynamicPrompt[k] = '(';
|
||||
}
|
||||
if( dynPrompt.zScannerAwaits ){
|
||||
int i = 0;
|
||||
const char *z = dynPrompt.zScannerAwaits;
|
||||
while( z[i] && k+nCore<PROMPT_LEN_MAX ){
|
||||
dynPrompt.dynamicPrompt[k++] = z[i++];
|
||||
}
|
||||
}
|
||||
while( k<nSpace ){
|
||||
dynPrompt.dynamicPrompt[k++] = ' ';
|
||||
}
|
||||
if( k>nSpace && nDot ){
|
||||
nSpace++;
|
||||
nDot--;
|
||||
}
|
||||
memcpy(&dynPrompt.dynamicPrompt[k],
|
||||
&continuePrompt[nSpace],
|
||||
nCore);
|
||||
return dynPrompt.dynamicPrompt;
|
||||
}
|
||||
#endif /* !defined(SQLITE_OMIT_DYNAPROMPT) */
|
||||
|
||||
/* Indicate out-of-memory and exit. */
|
||||
static void shell_out_of_memory(void){
|
||||
eputz("Error: out of memory\n");
|
||||
@@ -1048,7 +952,7 @@ static char *one_input_line(ShellState *p, char *zPrior, int isContinuation){
|
||||
if( in!=0 ){
|
||||
zResult = local_getline(zPrior, in);
|
||||
}else{
|
||||
zPrompt = isContinuation ? CONTINUATION_PROMPT(p) : mainPrompt;
|
||||
zPrompt = isContinuation ? continuePrompt : mainPrompt;
|
||||
#if SHELL_USE_LOCAL_GETLINE
|
||||
sputz(stdout, zPrompt);
|
||||
fflush(stdout);
|
||||
@@ -12076,112 +11980,28 @@ meta_command_exit:
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* Line scan result and intermediate states (supporting scan resumption)
|
||||
*/
|
||||
#ifndef CHAR_BIT
|
||||
# define CHAR_BIT 8
|
||||
#endif
|
||||
typedef enum {
|
||||
QSS_HasDark = 1<<CHAR_BIT,
|
||||
QSS_EndingSemi = 2<<CHAR_BIT,
|
||||
QSS_CharMask = (1<<CHAR_BIT)-1,
|
||||
QSS_ScanMask = 3<<CHAR_BIT,
|
||||
QSS_Start = 0
|
||||
} QuickScanState;
|
||||
#define QSS_SETV(qss, newst) ((newst) | ((qss) & QSS_ScanMask))
|
||||
#define QSS_INPLAIN(qss) (((qss)&QSS_CharMask)==QSS_Start)
|
||||
#define QSS_PLAINWHITE(qss) (((qss)&~QSS_EndingSemi)==QSS_Start)
|
||||
#define QSS_PLAINDARK(qss) (((qss)&~QSS_EndingSemi)==QSS_HasDark)
|
||||
#define QSS_SEMITERM(qss) (((qss)&~QSS_HasDark)==QSS_EndingSemi)
|
||||
|
||||
/*
|
||||
** Scan line for classification to guide shell's handling.
|
||||
** The scan is resumable for subsequent lines when prior
|
||||
** return values are passed as the 3rd argument (qss).
|
||||
** Test to see if a line consists entirely of whitespace.
|
||||
*/
|
||||
static QuickScanState quickscan(
|
||||
ShellState *p,
|
||||
char *zLine,
|
||||
QuickScanState qss,
|
||||
SCAN_TRACKER_REFTYPE pst
|
||||
){
|
||||
char cin;
|
||||
char cWait = (char)qss; /* intentional narrowing loss */
|
||||
if( cWait==0 ){
|
||||
PlainScan:
|
||||
while( (cin = *zLine++)!=0 ){
|
||||
if( IsSpace(cin) )
|
||||
continue;
|
||||
switch (cin){
|
||||
case '-':
|
||||
if( *zLine!='-' )
|
||||
break;
|
||||
while((cin = *++zLine)!=0 )
|
||||
if( cin=='\n')
|
||||
goto PlainScan;
|
||||
return qss;
|
||||
case ';':
|
||||
qss |= QSS_EndingSemi;
|
||||
continue;
|
||||
case '/':
|
||||
if( *zLine=='*' ){
|
||||
++zLine;
|
||||
cWait = '*';
|
||||
CONTINUE_PROMPT_AWAITS(p, pst, "/*");
|
||||
qss = QSS_SETV(qss, cWait);
|
||||
goto TermScan;
|
||||
}
|
||||
break;
|
||||
case '[':
|
||||
cWait = ']';
|
||||
qss = QSS_HasDark | cWait;
|
||||
CONTINUE_PROMPT_AWAITC(p, pst, cin);
|
||||
goto TermScan;
|
||||
case '`': case '\'': case '"':
|
||||
cWait = cin;
|
||||
qss = QSS_HasDark | cWait;
|
||||
CONTINUE_PROMPT_AWAITC(p, pst, cin);
|
||||
goto TermScan;
|
||||
case '(':
|
||||
CONTINUE_PAREN_INCR(p, pst, 1);
|
||||
break;
|
||||
case ')':
|
||||
CONTINUE_PAREN_INCR(p, pst, -1);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
qss = (qss & ~QSS_EndingSemi) | QSS_HasDark;
|
||||
static int line_is_all_whitespace(const char *z){
|
||||
for(; *z; z++){
|
||||
if( IsSpace(z[0]) ) continue;
|
||||
if( *z=='/' && z[1]=='*' ){
|
||||
z += 2;
|
||||
while( *z && (*z!='*' || z[1]!='/') ){ z++; }
|
||||
if( *z==0 ) return 0;
|
||||
z++;
|
||||
continue;
|
||||
}
|
||||
}else{
|
||||
TermScan:
|
||||
while( (cin = *zLine++)!=0 ){
|
||||
if( cin==cWait ){
|
||||
switch( cWait ){
|
||||
case '*':
|
||||
if( *zLine != '/' )
|
||||
continue;
|
||||
++zLine;
|
||||
CONTINUE_PROMPT_AWAITC(p, pst, 0);
|
||||
qss = QSS_SETV(qss, 0);
|
||||
goto PlainScan;
|
||||
case '`': case '\'': case '"':
|
||||
if(*zLine==cWait){
|
||||
/* Swallow doubled end-delimiter.*/
|
||||
++zLine;
|
||||
continue;
|
||||
}
|
||||
deliberate_fall_through; /* FALLTHRU */
|
||||
case ']':
|
||||
CONTINUE_PROMPT_AWAITC(p, pst, 0);
|
||||
qss = QSS_SETV(qss, 0);
|
||||
goto PlainScan;
|
||||
default: assert(0);
|
||||
}
|
||||
}
|
||||
if( *z=='-' && z[1]=='-' ){
|
||||
z += 2;
|
||||
while( *z && *z!='\n' ){ z++; }
|
||||
if( *z==0 ) return 1;
|
||||
continue;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
return qss;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -12189,15 +12009,16 @@ static QuickScanState quickscan(
|
||||
** than a semi-colon. The SQL Server style "go" command is understood
|
||||
** as is the Oracle "/".
|
||||
*/
|
||||
static int line_is_command_terminator(ShellState *p, char *zLine){
|
||||
static int line_is_command_terminator(const char *zLine){
|
||||
while( IsSpace(zLine[0]) ){ zLine++; };
|
||||
if( zLine[0]=='/' )
|
||||
zLine += 1; /* Oracle */
|
||||
else if ( ToLower(zLine[0])=='g' && ToLower(zLine[1])=='o' )
|
||||
zLine += 2; /* SQL Server */
|
||||
else
|
||||
return 0;
|
||||
return quickscan(p, zLine, QSS_Start, 0)==QSS_Start;
|
||||
if( zLine[0]=='/' && line_is_all_whitespace(&zLine[1]) ){
|
||||
return 1; /* Oracle */
|
||||
}
|
||||
if( ToLower(zLine[0])=='g' && ToLower(zLine[1])=='o'
|
||||
&& line_is_all_whitespace(&zLine[2]) ){
|
||||
return 1; /* SQL Server */
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -12430,8 +12251,8 @@ static int process_input(ShellState *p, const char *zSrc){
|
||||
i64 nAlloc = 0; /* Allocated zSql[] space */
|
||||
int rc; /* Error code */
|
||||
int errCnt = 0; /* Number of errors seen */
|
||||
int hasSemi = 0; /* Input line contains a semicolon */
|
||||
i64 startline = 0; /* Line number for start of current input */
|
||||
QuickScanState qss = QSS_Start; /* Accumulated line status (so far) */
|
||||
const char *saved_zInFile; /* Prior value of p->zInFile */
|
||||
i64 saved_lineno; /* Prior value of p->lineno */
|
||||
|
||||
@@ -12446,7 +12267,6 @@ static int process_input(ShellState *p, const char *zSrc){
|
||||
p->zInFile = zSrc;
|
||||
saved_lineno = p->lineno;
|
||||
p->lineno = 0;
|
||||
CONTINUE_PROMPT_RESET(p);
|
||||
while( errCnt==0 || !bail_on_error || (p->in==0 && stdin_is_interactive) ){
|
||||
fflush(p->out);
|
||||
zLine = one_input_line(p, zLine, nSql>0);
|
||||
@@ -12460,20 +12280,12 @@ static int process_input(ShellState *p, const char *zSrc){
|
||||
seenInterrupt = 0;
|
||||
}
|
||||
p->lineno++;
|
||||
if( QSS_INPLAIN(qss)
|
||||
&& line_is_command_terminator(p, zLine)
|
||||
&& line_is_complete(zSql, nSql) ){
|
||||
memcpy(zLine,";",2);
|
||||
}
|
||||
qss = quickscan(p, zLine, qss, CONTINUE_PROMPT_PSTATE(p));
|
||||
if( QSS_PLAINWHITE(qss) && nSql==0 ){
|
||||
if( nSql==0 && line_is_all_whitespace(zLine) ){
|
||||
/* Just swallow single-line whitespace */
|
||||
echo_group_input(p, zLine);
|
||||
qss = QSS_Start;
|
||||
continue;
|
||||
}
|
||||
if( zLine && (zLine[0]=='.' || zLine[0]=='#') && nSql==0 ){
|
||||
CONTINUE_PROMPT_RESET(p);
|
||||
echo_group_input(p, zLine);
|
||||
if( zLine[0]=='.' ){
|
||||
rc = do_meta_command(zLine, p);
|
||||
@@ -12483,10 +12295,12 @@ static int process_input(ShellState *p, const char *zSrc){
|
||||
errCnt++;
|
||||
}
|
||||
}
|
||||
qss = QSS_Start;
|
||||
continue;
|
||||
}
|
||||
/* No single-line dispositions remain; accumulate line(s). */
|
||||
if( line_is_command_terminator(zLine) && line_is_complete(zSql, nSql) ){
|
||||
memcpy(zLine,";",2);
|
||||
}
|
||||
hasSemi = strchr(zLine,';')!=0;
|
||||
nLine = strlen(zLine);
|
||||
if( nSql+nLine+2>=nAlloc ){
|
||||
/* Grow buffer by half-again increments when big. */
|
||||
@@ -12514,10 +12328,10 @@ static int process_input(ShellState *p, const char *zSrc){
|
||||
nSql = 0;
|
||||
errCnt++;
|
||||
break;
|
||||
}else if( nSql && QSS_SEMITERM(qss) && sqlite3_complete(zSql) ){
|
||||
}
|
||||
if( nSql && hasSemi && sqlite3_complete(zSql) ){
|
||||
echo_group_input(p, zSql);
|
||||
errCnt += runOneSqlLine(p, zSql, p->zInFile, startline);
|
||||
CONTINUE_PROMPT_RESET(p);
|
||||
nSql = 0;
|
||||
if( p->nPopOutput ){
|
||||
output_reset(p);
|
||||
@@ -12530,18 +12344,15 @@ static int process_input(ShellState *p, const char *zSrc){
|
||||
p->nPopMode = 0;
|
||||
}
|
||||
p->bSafeMode = p->bSafeModePersist;
|
||||
qss = QSS_Start;
|
||||
}else if( nSql && QSS_PLAINWHITE(qss) ){
|
||||
}else if( nSql && line_is_all_whitespace(zSql) ){
|
||||
echo_group_input(p, zSql);
|
||||
nSql = 0;
|
||||
qss = QSS_Start;
|
||||
}
|
||||
}
|
||||
if( nSql ){
|
||||
/* This may be incomplete. Let the SQL parser deal with that. */
|
||||
echo_group_input(p, zSql);
|
||||
errCnt += runOneSqlLine(p, zSql, p->zInFile, startline);
|
||||
CONTINUE_PROMPT_RESET(p);
|
||||
}
|
||||
free(zSql);
|
||||
free(zLine);
|
||||
|
||||
Reference in New Issue
Block a user