Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Get CLI utf8_fgets() to not consume more input than it returns. Get console setup restoration to happen for all non-crash exits. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | cli-utf8 |
Files: | files | file ages | folders |
SHA3-256: |
b4fa233d3dda54fa83771844cf5156bf |
User & Date: | larrybr 2023-04-13 14:14:27.434 |
Context
2023-04-14
| ||
19:56 | Cure CLI double-prompting (by ditching gcc fgetws()), general cleanup. Work remaining is to avoid effect of -utf8 when a line editor is linked/used as part of CLI. (check-in: 73a5f54231 user: larrybr tags: cli-utf8) | |
2023-04-13
| ||
14:14 | Get CLI utf8_fgets() to not consume more input than it returns. Get console setup restoration to happen for all non-crash exits. (check-in: b4fa233d3d user: larrybr tags: cli-utf8) | |
2023-04-12
| ||
17:54 | WIP: CLI option to take control of console on Windows and make it support UTF-8 input pasting (or typing). Needs work to become robust per "ToDo:". (check-in: 824382393d user: larrybr tags: cli-utf8) | |
Changes
Changes to src/shell.c.in.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | /* ** 2001 September 15 ** ** The author disclaims copyright to this source code. In place of ** a legal notice, here is a blessing: ** ** May you do good and not evil. ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains code to implement the "sqlite" command line ** utility for accessing SQLite databases. */ #if (defined(_WIN32) || defined(WIN32)) && !defined(_CRT_SECURE_NO_WARNINGS) /* This needs to come before any includes for MSVC compiler */ #define _CRT_SECURE_NO_WARNINGS #endif typedef unsigned int u32; typedef unsigned short int u16; /* | > | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | /* ** 2001 September 15 ** ** The author disclaims copyright to this source code. In place of ** a legal notice, here is a blessing: ** ** May you do good and not evil. ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains code to implement the "sqlite" command line ** utility for accessing SQLite databases. ToDo: The -utf8 option may not play well with line editing input libraries. */ #if (defined(_WIN32) || defined(WIN32)) && !defined(_CRT_SECURE_NO_WARNINGS) /* This needs to come before any includes for MSVC compiler */ #define _CRT_SECURE_NO_WARNINGS #endif typedef unsigned int u32; typedef unsigned short int u16; /* ** optionally #include a user-defined header, whereby compilation options ** may be set prior to where they take effect, but after platform setup. ** If SQLITE_CUSTOM_INCLUDE=? is defined, its value names the #include ** file. Note that this macro has a like effect on sqlite3.c compilation. */ # define SHELL_STRINGIFY_(f) #f # define SHELL_STRINGIFY(f) SHELL_STRINGIFY_(f) #ifdef SQLITE_CUSTOM_INCLUDE |
︙ | ︙ | |||
585 586 587 588 589 590 591 | } return dynPrompt.dynamicPrompt; } #endif /* !defined(SQLITE_OMIT_DYNAPROMPT) */ #if (defined(_WIN32) || defined(WIN32)) && !defined(SQLITE_SHELL_FIDDLE) static int infsMode; | | > | | 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 | } return dynPrompt.dynamicPrompt; } #endif /* !defined(SQLITE_OMIT_DYNAPROMPT) */ #if (defined(_WIN32) || defined(WIN32)) && !defined(SQLITE_SHELL_FIDDLE) static int infsMode; static UINT codePage = 0; static HANDLE hConsoleIn; static DWORD consoleMode; /* ** Prepare input stream, (if known to be a WIN32 console), for UTF-8 ** input (from either typing or suitable paste operations) and for ** UTF-8 rendering. This may "fail" with a message to stderr, where ** the preparation is not done and common "code page" issues occur. */ static void instream_prepare(void){ if( isatty(0) ){ if( !IsValidCodePage(CP_UTF8) ){ fprintf(stderr, "Cannot use UTF-8 code page.\n"); console_utf8 = 0; return; } codePage = GetConsoleCP(); |
︙ | ︙ | |||
616 617 618 619 620 621 622 | console_utf8 = 0; } } /* ** Undo the effects of instream_prepare(), if any. */ | | | > < < < > < | | | > > > > > > | > | | > > | > | < < | | 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 | console_utf8 = 0; } } /* ** Undo the effects of instream_prepare(), if any. */ static void SQLITE_CDECL instream_restore(void){ if( console_utf8 && codePage!=0 ){ _setmode(_fileno(stdin), infsMode); SetConsoleCP(codePage); SetConsoleMode( hConsoleIn, consoleMode ); console_utf8 = 0; /* Avoid multiple calls. */ } } /* ** Collect input like fgets(...) with special provisions for input ** from the Windows console to get around its strange coding issues. ** Defers to plain fgets() when input is not interactive or when the ** startup option, -utf8, has not been provided or taken effect. */ static char* utf8_fgets(char *buf, int ncmax, FILE *fin){ #define SQLITE_IA_LINE_LEN 150 if( fin==stdin && stdin_is_interactive && console_utf8 ){ wchar_t wbuf[SQLITE_IA_LINE_LEN]; int noc = 0; if( ncmax == 0 ) return 0; buf[0] = 0; while( noc < ncmax-7-1 ){ /* There is room for at least 2 more characters and the 0-terminator. */ int na = (ncmax-1 - noc)/4; wchar_t * wz; if( na > SQLITE_IA_LINE_LEN ) na = SQLITE_IA_LINE_LEN; wz = fgetws(wbuf, na, stdin); if( wz != 0 ){ int nmb = WideCharToMultiByte(CP_UTF8, 0, wz, -1, 0, 0, 0, 0); if( nmb !=0 && noc+nmb <= ncmax ){ WideCharToMultiByte(CP_UTF8, 0, wz, -1, buf+noc, nmb, 0, 0); noc += nmb-1; /* Strip 0-terminator added by above call. */ if( buf[noc-1] == '\n' ) break; }else break; /* Drop apparent garbage in. (Could assert.) */ }else break; } if( noc == 0 ) return 0; return buf; }else{ return fgets(buf, ncmax, fin); } } # define fgets(b,n,f) utf8_fgets(b,n,f) |
︙ | ︙ | |||
11785 11786 11787 11788 11789 11790 11791 | #if SQLITE_SHELL_IS_UTF8 int SQLITE_CDECL main(int argc, char **argv){ #else int SQLITE_CDECL wmain(int argc, wchar_t **wargv){ char **argv; #endif #ifdef SQLITE_DEBUG | | | 11793 11794 11795 11796 11797 11798 11799 11800 11801 11802 11803 11804 11805 11806 11807 | #if SQLITE_SHELL_IS_UTF8 int SQLITE_CDECL main(int argc, char **argv){ #else int SQLITE_CDECL wmain(int argc, wchar_t **wargv){ char **argv; #endif #ifdef SQLITE_DEBUG sqlite3_int64 mem_main_enter = 0; #endif char *zErrMsg = 0; #ifdef SQLITE_SHELL_FIDDLE # define data shellState #else ShellState data; #endif |
︙ | ︙ | |||
11817 11818 11819 11820 11821 11822 11823 | stdin_is_interactive = 0; stdout_is_console = 1; data.wasm.zDefaultDbName = "/fiddle.sqlite3"; #else stdin_is_interactive = isatty(0); stdout_is_console = isatty(1); #endif | | > > > > > | 11825 11826 11827 11828 11829 11830 11831 11832 11833 11834 11835 11836 11837 11838 11839 11840 11841 11842 11843 11844 | stdin_is_interactive = 0; stdout_is_console = 1; data.wasm.zDefaultDbName = "/fiddle.sqlite3"; #else stdin_is_interactive = isatty(0); stdout_is_console = isatty(1); #endif #if (defined(_WIN32) || defined(WIN32)) && !defined(SQLITE_SHELL_FIDDLE) atexit(instream_restore); /* Needs revision for CLI as library call */ #endif #ifdef SQLITE_DEBUG mem_main_enter = sqlite3_memory_used(); #endif #if !defined(_WIN32_WCE) if( getenv("SQLITE_DEBUG_BREAK") ){ if( isatty(0) && isatty(2) ){ fprintf(stderr, "attach debugger to process %d and press any key to continue.\n", GETPID()); fgetc(stdin); |
︙ | ︙ | |||
12366 12367 12368 12369 12370 12371 12372 | free(zHistory); } }else{ data.in = stdin; rc = process_input(&data); } } | < < < < < | 12379 12380 12381 12382 12383 12384 12385 12386 12387 12388 12389 12390 12391 12392 | free(zHistory); } }else{ data.in = stdin; rc = process_input(&data); } } #ifndef SQLITE_SHELL_FIDDLE /* In WASM mode we have to leave the db state in place so that ** client code can "push" SQL into it after this call returns. */ free(azCmd); set_table_name(&data, 0); if( data.db ){ session_close_all(&data, -1); |
︙ | ︙ |