Input working. No line-editor provisions yet. (WIP, but suitable for testing.)
FossilOrigin-Name: e8568b1d925c2118eb08394dd8aa50cfb521240f87668f535ec4a03e67dc9a09
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
C Setup,\stakedown,\smode\sset\sand\soutput\sworking.\sNo\sinput\syet.\s(WIP)
|
||||
D 2023-11-05T01:21:14.743
|
||||
C Input\sworking.\sNo\sline-editor\sprovisions\syet.\s(WIP,\sbut\ssuitable\sfor\stesting.)
|
||||
D 2023-11-05T19:42:00.134
|
||||
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
|
||||
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
|
||||
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
|
||||
@@ -669,8 +669,8 @@ F src/btreeInt.h ef12a72b708677e48d6bc8dcd66fed25434740568b89e2cfa368093cfc5b9d1
|
||||
F src/build.c 189e4517d67f09f0a3e0d8e1faa6e2ef0c2e95f6ac82e33c912cb7efa2a359cc
|
||||
F src/callback.c db3a45e376deff6a16c0058163fe0ae2b73a2945f3f408ca32cf74960b28d490
|
||||
F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e
|
||||
F src/console_io.c 484a4ad56c18ddc62b845494f8ac6e06df9f9b0bc2fa60ac2dcba74635bdf8da x
|
||||
F src/console_io.h 6b7c86a5778445e507a089b9808803e4523e2989f33c04692e008eae3f0f4d8a
|
||||
F src/console_io.c a04f62d1930d32f0bda26b546e9b3d6455e7caaee4ea7624be4b1ef7ea2329b7 x
|
||||
F src/console_io.h 49680984d2a121697ccb2620f9e8465393d61c3edc3d5720c77dfa0a1f4a7389
|
||||
F src/ctime.c 23331529e654be40ca97d171cbbffe9b3d4c71cc53b78fe5501230675952da8b
|
||||
F src/date.c eebc54a00e888d3c56147779e9f361b77d62fd69ff2008c5373946aa1ba1d574
|
||||
F src/dbpage.c 80e46e1df623ec40486da7a5086cb723b0275a6e2a7b01d9f9b5da0f04ba2782
|
||||
@@ -2144,8 +2144,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
|
||||
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
|
||||
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
|
||||
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
|
||||
P 64abef8314b8544fdc7b71317d61a4641dc607a1ae42b8ff21543226fd338ba2
|
||||
R 9aec452b903f28bc0cbf638b7c11370e
|
||||
P dfea85be1fb927ea446c9d98bae42ba1197bdab098aa6d95aa512a37d07a1e52
|
||||
R 4898fd3a7f002f1e4e422622974a0785
|
||||
U larrybr
|
||||
Z 37ecbe5d111f6f842b9b1e97c1e0e0d1
|
||||
Z c9314460b6b28a6cd16041af96151d83
|
||||
# Remove this line to create a well-formed Fossil manifest.
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
dfea85be1fb927ea446c9d98bae42ba1197bdab098aa6d95aa512a37d07a1e52
|
||||
e8568b1d925c2118eb08394dd8aa50cfb521240f87668f535ec4a03e67dc9a09
|
||||
+203
-109
@@ -8,7 +8,7 @@
|
||||
** May you find forgiveness for yourself and forgive others.
|
||||
** May you share freely, never taking more than you give.
|
||||
**
|
||||
*************************************************************************
|
||||
********************************************************************************
|
||||
** This file implements various interfaces used for console I/O by the
|
||||
** SQLite project command-line tools, as explained in console_io.h .
|
||||
*/
|
||||
@@ -28,7 +28,7 @@
|
||||
# ifdef SHELL_LEGACY_CONSOLE_IO
|
||||
# define SHELL_CON_TRANSLATE 2 /* Use UTF-8/MBCS translation for console I/O */
|
||||
# else
|
||||
# define SHELL_CON_TRANSLATE 1 /* Use wchar APIs for console I/O */
|
||||
# define SHELL_CON_TRANSLATE 1 /* Use WCHAR Windows APIs for console I/O */
|
||||
# endif
|
||||
#else
|
||||
# include <unistd.h>
|
||||
@@ -45,91 +45,102 @@ static HANDLE handleOfFile(FILE *pf){
|
||||
}
|
||||
#endif
|
||||
|
||||
static short fileOfConsole(FILE *pf){
|
||||
typedef struct PerStreamTags {
|
||||
#if SHELL_CON_TRANSLATE
|
||||
DWORD consMode;
|
||||
HANDLE hx;
|
||||
#endif
|
||||
FILE *pf;
|
||||
} PerStreamTags;
|
||||
|
||||
static short fileOfConsole(FILE *pf, PerStreamTags *ppst){
|
||||
#if SHELL_CON_TRANSLATE
|
||||
short rv = 0;
|
||||
DWORD dwj;
|
||||
HANDLE fh = handleOfFile(pf);
|
||||
if( INVALID_HANDLE_VALUE != fh ){
|
||||
return (GetFileType(fh) == FILE_TYPE_CHAR && GetConsoleMode(fh,&dwj));
|
||||
}else return 0;
|
||||
rv = (GetFileType(fh) == FILE_TYPE_CHAR && GetConsoleMode(fh,&dwj));
|
||||
if( rv ){
|
||||
ppst->hx = fh;
|
||||
ppst->pf = pf;
|
||||
GetConsoleMode(fh, &ppst->consMode);
|
||||
}
|
||||
}
|
||||
return rv;
|
||||
#else
|
||||
return (short)isatty(fileno(pf));
|
||||
#endif
|
||||
}
|
||||
|
||||
#define SHELL_INVALID_FILE_PTR ((FILE *)sizeof(FILE*))
|
||||
#define SHELL_INVALID_CONS_MODE 0xFFFF0000
|
||||
|
||||
#if SHELL_CON_TRANSLATE
|
||||
# define SHELL_CONI_MODE \
|
||||
(ENABLE_ECHO_INPUT | ENABLE_INSERT_MODE | ENABLE_LINE_INPUT | 0x80 \
|
||||
| ENABLE_QUICK_EDIT_MODE | ENABLE_EXTENDED_FLAGS | ENABLE_PROCESSED_INPUT)
|
||||
# define SHELL_CONO_MODE (ENABLE_PROCESSED_OUTPUT | ENABLE_WRAP_AT_EOL_OUTPUT \
|
||||
| ENABLE_VIRTUAL_TERMINAL_PROCESSING)
|
||||
#endif
|
||||
|
||||
typedef struct ConsoleInfo {
|
||||
/* int iDefaultFmode; */
|
||||
ConsoleStdConsStreams cscs;
|
||||
/* int iInitialFmode[3];
|
||||
** Above only needed for legacy console I/O for callable CLI.
|
||||
** Because that state cannot be obtained from each FILE *,
|
||||
** there will be no exact restoration of console state for
|
||||
** the CLI when built with SHELL_LEGACY_CONSOLE_IO defined.
|
||||
*/
|
||||
PerStreamTags pst[3];
|
||||
#if SHELL_CON_TRANSLATE
|
||||
HANDLE hIn; HANDLE hOut; HANDLE hErr;
|
||||
HANDLE hLowest;
|
||||
unsigned char haveInput;
|
||||
unsigned char outputIx;
|
||||
unsigned char stdinEof;
|
||||
#endif
|
||||
FILE *pfIn; FILE *pfOut; FILE *pfErr;
|
||||
ConsoleStdConsStreams cscs;
|
||||
} ConsoleInfo;
|
||||
|
||||
static ConsoleInfo consoleInfo = {
|
||||
/* 0, iDefaultFmode */
|
||||
CSCS_NoConsole,
|
||||
#if SHELL_CON_TRANSLATE
|
||||
INVALID_HANDLE_VALUE, INVALID_HANDLE_VALUE, INVALID_HANDLE_VALUE,
|
||||
INVALID_HANDLE_VALUE,
|
||||
# define CI_INITIALIZER \
|
||||
{SHELL_INVALID_CONS_MODE, INVALID_HANDLE_VALUE, SHELL_INVALID_FILE_PTR }
|
||||
#else
|
||||
# define CI_INITIALIZER { SHELL_INVALID_FILE_PTR }
|
||||
#endif
|
||||
SHELL_INVALID_FILE_PTR, SHELL_INVALID_FILE_PTR, SHELL_INVALID_FILE_PTR
|
||||
};
|
||||
#undef SHELL_INVALID_FILE_PTR
|
||||
|
||||
#if SHELL_CON_TRANSLATE == 1
|
||||
# define SHELL_CON_MODE_CSZ _O_U16TEXT
|
||||
#elif SHELL_CON_TRANSLATE == 2
|
||||
# define SHELL_CON_MODE_CSZ _O_U8TEXT
|
||||
static ConsoleInfo consoleInfo = {
|
||||
/* {0,0,0}, // iInitialFmode */
|
||||
{ /* pst */ CI_INITIALIZER, CI_INITIALIZER, CI_INITIALIZER },
|
||||
#if SHELL_CON_TRANSLATE
|
||||
0, 0, 1, /* haveInput, outputIx, stdinEof */
|
||||
#endif
|
||||
CSCS_NoConsole
|
||||
};
|
||||
#undef CI_INITIALIZER
|
||||
|
||||
INT_LINKAGE ConsoleStdConsStreams
|
||||
consoleClassifySetup( FILE *pfIn, FILE *pfOut, FILE *pfErr ){
|
||||
ConsoleStdConsStreams rv = CSCS_NoConsole;
|
||||
if( fileOfConsole(pfErr) ){
|
||||
rv |= CSCS_ErrConsole;
|
||||
consoleInfo.pfErr = pfErr;
|
||||
FILE *apf[3] = { pfIn, pfOut, pfErr };
|
||||
int ix;
|
||||
for( ix = 2; ix >= 0; --ix ){
|
||||
PerStreamTags *ppst = &consoleInfo.pst[ix];
|
||||
if( fileOfConsole(apf[ix], ppst) ){
|
||||
#if SHELL_CON_TRANSLATE
|
||||
fflush(pfErr);
|
||||
# if SHELL_CON_TRANSLATE == 1
|
||||
_setmode(_fileno(pfErr), _O_U16TEXT);
|
||||
_setmode(_fileno(pfErr), _O_BINARY);
|
||||
# elif SHELL_CON_TRANSLATE == 2
|
||||
_setmode(_fileno(pfErr), _O_U8TEXT);
|
||||
_setmode(_fileno(pfErr), _O_TEXT);
|
||||
# endif
|
||||
consoleInfo.hLowest = consoleInfo.hErr = handleOfFile(pfErr);
|
||||
DWORD cm = (ix==0)? SHELL_CONI_MODE : SHELL_CONO_MODE;
|
||||
if( ix==0 ){
|
||||
consoleInfo.haveInput = 1;
|
||||
consoleInfo.stdinEof = 0;
|
||||
}else{
|
||||
consoleInfo.outputIx |= ix;
|
||||
}
|
||||
SetConsoleMode(ppst->hx, cm);
|
||||
fprintf(stderr, "consMode[%d]: %02x -> %02x\n", ix, ppst->consMode, cm);
|
||||
#endif
|
||||
}
|
||||
if( fileOfConsole(pfOut) ){
|
||||
rv |= CSCS_OutConsole;
|
||||
consoleInfo.pfOut = pfOut;
|
||||
#if SHELL_CON_TRANSLATE
|
||||
fflush(pfOut);
|
||||
# if SHELL_CON_TRANSLATE == 1
|
||||
_setmode(_fileno(pfOut), _O_U16TEXT);
|
||||
_setmode(_fileno(pfOut), _O_BINARY);
|
||||
# elif SHELL_CON_TRANSLATE == 2
|
||||
_setmode(_fileno(pfOut), _O_U8TEXT);
|
||||
_setmode(_fileno(pfOut), _O_TEXT);
|
||||
# endif
|
||||
consoleInfo.hLowest = consoleInfo.hOut = handleOfFile(pfOut);
|
||||
#endif
|
||||
}
|
||||
if( fileOfConsole(pfIn) ){
|
||||
rv |= CSCS_InConsole;
|
||||
consoleInfo.pfIn = pfIn;
|
||||
#if SHELL_CON_TRANSLATE == 1
|
||||
_setmode(_fileno(pfIn), _O_U16TEXT);
|
||||
_setmode(_fileno(pfIn), _O_BINARY);
|
||||
consoleInfo.hLowest = consoleInfo.hIn = handleOfFile(pfIn);
|
||||
#elif SHELL_CON_TRANSLATE == 2
|
||||
_setmode(_fileno(pfIn), _O_U8TEXT);
|
||||
_setmode(_fileno(pfIn), _O_TEXT);
|
||||
consoleInfo.hLowest = consoleInfo.hIn = handleOfFile(pfIn);
|
||||
rv |= (CSCS_InConsole<<ix);
|
||||
}
|
||||
if( ix > 0 ) fflush(apf[ix]);
|
||||
#if SHELL_CON_TRANSLATE == 2
|
||||
_setmode(_fileno(apf[ix]), _O_U8TEXT);
|
||||
_setmode(_fileno(apf[ix]), _O_TEXT);
|
||||
#endif
|
||||
}
|
||||
consoleInfo.cscs = rv;
|
||||
@@ -137,66 +148,69 @@ consoleClassifySetup( FILE *pfIn, FILE *pfOut, FILE *pfErr ){
|
||||
}
|
||||
|
||||
INT_LINKAGE void SQLITE_CDECL consoleRestore( void ){
|
||||
#if SHELL_CON_TRANSLATE
|
||||
if( consoleInfo.cscs ){
|
||||
/* ToDo: Read these modes in consoleClassifySetup somehow.
|
||||
** A _get_fmode() call almost works. But not with gcc, yet.
|
||||
** This has to be done to make the CLI a callable function.
|
||||
*/
|
||||
int tmode = _O_TEXT, xmode = _O_U8TEXT;
|
||||
if( consoleInfo.cscs & CSCS_InConsole ){
|
||||
_setmode(_fileno(consoleInfo.pfIn), tmode);
|
||||
_setmode(_fileno(consoleInfo.pfIn), xmode);
|
||||
}
|
||||
if( consoleInfo.cscs & CSCS_OutConsole ){
|
||||
_setmode(_fileno(consoleInfo.pfOut), tmode);
|
||||
_setmode(_fileno(consoleInfo.pfOut), xmode);
|
||||
}
|
||||
if( consoleInfo.cscs & CSCS_ErrConsole ){
|
||||
_setmode(_fileno(consoleInfo.pfErr), tmode);
|
||||
_setmode(_fileno(consoleInfo.pfErr), xmode);
|
||||
int ix;
|
||||
for( ix=0; ix<3; ++ix ){
|
||||
if( consoleInfo.cscs & (CSCS_InConsole<<ix) ){
|
||||
PerStreamTags *ppst = &consoleInfo.pst[ix];
|
||||
#if SHELL_CON_TRANSLATE == 2
|
||||
static int tmode = _O_TEXT, xmode = _O_U8TEXT;
|
||||
/* Consider: Read these modes in consoleClassifySetup somehow.
|
||||
** A _get_fmode() call almost works. But not with gcc, yet.
|
||||
** This has to be done to make the CLI a callable function
|
||||
** when legacy console I/O is done. (This may never happen.)
|
||||
*/
|
||||
_setmode(_fileno(consoleInfo.pst[ix].pf), tmode);
|
||||
_setmode(_fileno(consoleInfo.pst[ix].pf), xmode);
|
||||
#endif
|
||||
#if SHELL_CON_TRANSLATE
|
||||
SetConsoleMode(ppst->hx, ppst->consMode);
|
||||
ppst->hx = INVALID_HANDLE_VALUE;
|
||||
#endif
|
||||
ppst->pf = SHELL_INVALID_FILE_PTR;
|
||||
}
|
||||
consoleInfo.cscs = CSCS_NoConsole;
|
||||
#if SHELL_CON_TRANSLATE
|
||||
consoleInfo.stdinEof = consoleInfo.haveInput = consoleInfo.outputIx= 0;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#ifdef TEST_CIO
|
||||
#endif
|
||||
}
|
||||
#undef SHELL_INVALID_FILE_PTR
|
||||
|
||||
static short isConOut(FILE *pf){
|
||||
if( pf==consoleInfo.pfOut ) return 1;
|
||||
else if( pf==consoleInfo.pfErr ) return 2;
|
||||
if( pf==consoleInfo.pst[1].pf ) return 1;
|
||||
else if( pf==consoleInfo.pst[2].pf ) return 2;
|
||||
else return 0;
|
||||
}
|
||||
|
||||
INT_LINKAGE void setBinaryMode(FILE *pf, short bFlush){
|
||||
#if SHELL_CON_TRANSLATE
|
||||
static void setModeFlushQ(FILE *pf, short bFlush, int mode){
|
||||
short ico = isConOut(pf);
|
||||
if( ico || bFlush ) fflush(pf);
|
||||
#if SHELL_CON_TRANSLATE == 2
|
||||
_setmode(_fileno(pf), _O_BINARY);
|
||||
#elif SHELL_CON_TRANSLATE == 1
|
||||
/* Never change between text/binary on UTF-16 console streamss. */
|
||||
if( !ico && !(consoleInfo.pfIn==pf)) _setmode(_fileno(pf), _O_BINARY);
|
||||
if( ico>1 || bFlush ) fflush(pf);
|
||||
_setmode(_fileno(pf), mode);
|
||||
}
|
||||
#else
|
||||
# define setModeFlushQ(f, b, m) if(isConOut(f)>0||b) fflush(f)
|
||||
#endif
|
||||
|
||||
INT_LINKAGE void setBinaryMode(FILE *pf, short bFlush){
|
||||
setModeFlushQ(pf, bFlush, _O_BINARY);
|
||||
}
|
||||
INT_LINKAGE void setTextMode(FILE *pf, short bFlush){
|
||||
short ico = isConOut(pf);
|
||||
if( ico || bFlush ) fflush(pf);
|
||||
#if SHELL_CON_TRANSLATE == 2
|
||||
_setmode(_fileno(pf), _O_TEXT);
|
||||
#elif SHELL_CON_TRANSLATE == 1
|
||||
/* Never change between text/binary on UTF-16 console streamss. */
|
||||
if( !ico && !(consoleInfo.pfIn==pf)) _setmode(_fileno(pf), _O_TEXT);
|
||||
#endif
|
||||
setModeFlushQ(pf, bFlush, _O_TEXT);
|
||||
}
|
||||
/* Later: Factor common code out of above 2 procs. */
|
||||
#undef setModeFlushQ
|
||||
|
||||
INT_LINKAGE int fprintfUtf8(FILE *pfO, const char *zFormat, ...){
|
||||
va_list ap;
|
||||
int rv = 0;
|
||||
short on = isConOut(pfO);
|
||||
va_start(ap, zFormat);
|
||||
if( on > 0 ){
|
||||
#if SHELL_CON_TRANSLATE
|
||||
short on = isConOut(pfO);
|
||||
#endif
|
||||
va_start(ap, zFormat);
|
||||
#if SHELL_CON_TRANSLATE
|
||||
if( on > 0 ){
|
||||
char *z1 = sqlite3_vmprintf(zFormat, ap);
|
||||
# if SHELL_CON_TRANSLATE == 2
|
||||
/* Legacy translation to active code page, then MBCS chars out. */
|
||||
@@ -216,7 +230,7 @@ INT_LINKAGE int fprintfUtf8(FILE *pfO, const char *zFormat, ...){
|
||||
if( nwc>0 ){
|
||||
zw2 = sqlite3_malloc64((nwc+1)*sizeof(WCHAR));
|
||||
if( zw2!=NULL ){
|
||||
HANDLE ho = (on==1)? consoleInfo.hOut : consoleInfo.hErr;
|
||||
HANDLE ho = (on==1)? consoleInfo.pst[1].hx : consoleInfo.pst[2].hx;
|
||||
nwc = MultiByteToWideChar(CP_UTF8,0,z1,rv,zw2,nwc);
|
||||
zw2[nwc] = 0;
|
||||
WriteConsoleW(ho, zw2, nwc, 0, NULL);
|
||||
@@ -226,32 +240,112 @@ INT_LINKAGE int fprintfUtf8(FILE *pfO, const char *zFormat, ...){
|
||||
}
|
||||
# endif
|
||||
sqlite3_free(z1);
|
||||
#else
|
||||
#endif
|
||||
}else{
|
||||
#endif
|
||||
rv = vfprintf(pfO, zFormat, ap);
|
||||
#if SHELL_CON_TRANSLATE
|
||||
}
|
||||
#endif
|
||||
va_end(ap);
|
||||
return rv;
|
||||
}
|
||||
|
||||
INT_LINKAGE int fgetsUtf8(char *buf, int ncMax, FILE *pfIn){
|
||||
return 0;
|
||||
INT_LINKAGE char* fgetsUtf8(char *cBuf, int ncMax, FILE *pfIn){
|
||||
if( pfIn==0 ) pfIn = stdin;
|
||||
#if SHELL_CON_TRANSLATE
|
||||
if( pfIn == consoleInfo.pst[0].pf ){
|
||||
static const int nwcLen = 150;
|
||||
WCHAR wcBuf[nwcLen+1];
|
||||
int lend = 0, noc = 0;
|
||||
if( consoleInfo.stdinEof ) return 0;
|
||||
if( ncMax > 0 ) cBuf[0] = 0;
|
||||
while( noc < ncMax-8-1 && !lend ){
|
||||
/* There is room for at least 2 more characters and a 0-terminator. */
|
||||
int na = (ncMax > nwcLen*4+1 + noc)? nwcLen : (ncMax-1 - noc)/4;
|
||||
DWORD nbr = 0;
|
||||
BOOL bRC = ReadConsoleW(consoleInfo.pst[0].hx, wcBuf, na, &nbr, 0);
|
||||
if( bRC && nbr>0 && (wcBuf[nbr-1]&0xF800)==0xD800 ){
|
||||
/* Last WHAR read is first of a UTF-16 surrogate pair. Grab its mate. */
|
||||
DWORD nbrx;
|
||||
bRC &= ReadConsoleW(consoleInfo.pst[0].hx, wcBuf+nbr, 1, &nbrx, 0);
|
||||
if( bRC ) nbr += nbrx;
|
||||
}
|
||||
hd(wcBuf,nbr);
|
||||
if( !bRC || (noc==0 && nbr==0) ) return 0;
|
||||
if( nbr > 0 ){
|
||||
int nmb = WideCharToMultiByte(CP_UTF8, 0, wcBuf,nbr,0,0,0,0);
|
||||
if( nmb != 0 && noc+nmb <= ncMax ){
|
||||
int iseg = noc;
|
||||
nmb = WideCharToMultiByte(CP_UTF8, 0, wcBuf,nbr,cBuf+noc,nmb,0,0);
|
||||
noc += nmb;
|
||||
/* Fixup line-ends as coded by Windows for CR (or "Enter".)
|
||||
** Note that this is done without regard for any setModeText()
|
||||
** call that might have been done on the interactive input.
|
||||
*/
|
||||
if( noc > 0 ){
|
||||
if( cBuf[noc-1]=='\n' ){
|
||||
lend = 1;
|
||||
if( noc > 1 && cBuf[noc-2]=='\r' ){
|
||||
cBuf[noc-2] = '\n';
|
||||
--noc;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Check for ^Z (anywhere in line) too. */
|
||||
while( iseg < noc ){
|
||||
if( cBuf[iseg]==0x1a ){
|
||||
consoleInfo.stdinEof = 1;
|
||||
noc = iseg; /* Chop ^Z and anything following. */
|
||||
break;
|
||||
}
|
||||
++iseg;
|
||||
}
|
||||
}else break; /* Drop apparent garbage in. (Could assert.) */
|
||||
}else break;
|
||||
}
|
||||
/* If got nothing, (after ^Z chop), must be at end-of-file. */
|
||||
if( noc == 0 ) return 0;
|
||||
cBuf[noc] = 0;
|
||||
return cBuf;
|
||||
}else{
|
||||
#endif
|
||||
return fgets(cBuf, ncMax, pfIn);
|
||||
#if SHELL_CON_TRANSLATE
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef TEST_CIO
|
||||
// cl -Zi -I. -DWIN32 -DTEST_CIO sqlite3.c src/console_io.c -Fecio.exe
|
||||
// gcc -I. -DWIN32 -DTEST_CIO -o cio sqlite3.c src/console_io.c -o cio.exe
|
||||
// gcc -I. -DWIN32 -DTEST_CIO sqlite3.c src/console_io.c -o cio.exe
|
||||
const char *prompts[] = { "main", "cont" };
|
||||
Prompts goofy = { 2, prompts };
|
||||
|
||||
int main(int na, char *av[]){
|
||||
ConsoleStdConsStreams cc = consoleClassifySetup(stdin, stdout, stderr);
|
||||
const char *zt = "Math: ±×÷∂∆∙√∞∩∫≈≠≡≤≥\n"
|
||||
"Hiragana: 亜唖娃阿哀愛挨姶逢葵茜穐悪握渥旭葦芦鯵梓圧斡扱"
|
||||
"宛姐虻飴絢綾鮎或粟袷安庵按暗案闇鞍杏\n"
|
||||
"Simplified Chinese: 餐参蚕残惭惨灿掺孱骖璨粲黪\n"
|
||||
"Geometric Shapes: ■□▪▫▲△▼▽◆◇◊○◌◎●◢◣◤◥◦\n"
|
||||
"Boxes single: ─━│┃┄┅┆┇┈┉┊┋ ┌┍┎┏┐┑┒┓└┕┖┗┘┙┚┛├┝┞┟┠┡┢┣┤┥┦┧┨┩┪┫┬┭┮┯┰┱┲┳"
|
||||
"┴┵┶┷┸┹┺┻┼┽┾┿╀╁╂╃╄╅╆╇╈╉╊╋\n"
|
||||
"Boxes double: ═║╒╓╔╕╖╗╘╙╚╛╜╝╞╟╠╡╢╣╤╥╦╧╨╩╪╫╬\n"
|
||||
"Rounded corners and diagonals: ╭╮╯╰╱╲╳\n"
|
||||
;
|
||||
char inBuf[150];
|
||||
setTextMode(stdout, 1);
|
||||
setTextMode(stderr, 1);
|
||||
fprintfUtf8(stderr, "%d\n", cc);
|
||||
fprintfUtf8(stderr, "Console streams: %d, CP_UTF8 valid: %d\n", cc,
|
||||
IsValidCodePage(CP_UTF8));
|
||||
fprintfUtf8(stdout, "%s=%d\n", "∑(1st 7 primes)", 42);
|
||||
fprintfUtf8(stderr, "%s\n", "∫ (1/x) dx ≡ ln(x)");
|
||||
fprintfUtf8(stdout, "%s", zt);
|
||||
fprintfUtf8(stderr, "Entering input/echo loop."
|
||||
" Type or copy/paste, or EOF to exit.\n");
|
||||
while( fprintfUtf8(stdout,"? ") && fgetsUtf8(inBuf, sizeof(inBuf), stdin) ){
|
||||
fprintfUtf8(stdout, "! %s", inBuf);
|
||||
}
|
||||
consoleRestore();
|
||||
return 0;
|
||||
}
|
||||
|
||||
+17
-5
@@ -60,6 +60,10 @@ typedef enum ConsoleStdConsStreams {
|
||||
**
|
||||
** On some platforms, stream or console mode alteration (aka
|
||||
** "Setup") may be made which is undone by consoleRestore().
|
||||
**
|
||||
** Applications which run an inferior (child) process which
|
||||
** inherits the same I/O streams may call this function after
|
||||
** such a process exits to guard against console mode changes.
|
||||
*/
|
||||
INT_LINKAGE ConsoleStdConsStreams
|
||||
consoleClassifySetup( FILE *pfIn, FILE *pfOut, FILE *pfErr );
|
||||
@@ -70,7 +74,13 @@ consoleClassifySetup( FILE *pfIn, FILE *pfOut, FILE *pfErr );
|
||||
** This should be called after consoleClassifySetup() and
|
||||
** before the process terminates normally. It is suitable
|
||||
** for use with the atexit() C library procedure. After
|
||||
** this call, no I/O should be done with the console.
|
||||
** this call, no I/O should be done with the console
|
||||
** until consoleClassifySetup(...) is called again.
|
||||
**
|
||||
** Applications which run an inferior (child) process that
|
||||
** inherits the same I/O streams might call this procedure
|
||||
** before so that said process will have a console setup
|
||||
** however users have configured it or come to expect.
|
||||
*/
|
||||
INT_LINKAGE void SQLITE_CDECL consoleRestore( void );
|
||||
|
||||
@@ -87,9 +97,10 @@ INT_LINKAGE int fprintfUtf8(FILE *pfO, const char *zFormat, ...);
|
||||
** Collect input like fgets(...) with special provisions for input
|
||||
** from the console on platforms that require same. Defers to the
|
||||
** C library fgets() when input is not from the console. Newline
|
||||
** translation may be done as set by set{Binary,Text}Mode().
|
||||
** translation may be done as set by set{Binary,Text}Mode(). As a
|
||||
** convenience, pfIn==NULL is treated as stdin.
|
||||
*/
|
||||
INT_LINKAGE int fgetsUtf8(char *buf, int ncMax, FILE *pfIn);
|
||||
INT_LINKAGE char* fgetsUtf8(char *cBuf, int ncMax, FILE *pfIn);
|
||||
|
||||
/*
|
||||
** Set given stream for binary mode, where newline translation is
|
||||
@@ -100,8 +111,9 @@ INT_LINKAGE int fgetsUtf8(char *buf, int ncMax, FILE *pfIn);
|
||||
** An additional side-effect is that if the stream is one passed
|
||||
** to consoleClassifySetup() as an output, it is flushed first.
|
||||
**
|
||||
** Note that binary/text mode has no effect on console output
|
||||
** translation. Newline chars start a new line on all platforms.
|
||||
** Note that binary/text mode has no effect on console I/O
|
||||
** translation. On all platforms, newline to the console starts
|
||||
** a new line and CR,LF chars from the console become a newline.
|
||||
*/
|
||||
INT_LINKAGE void setBinaryMode(FILE *, short bFlush);
|
||||
INT_LINKAGE void setTextMode(FILE *, short bFlush);
|
||||
|
||||
Reference in New Issue
Block a user