Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | 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. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | cli-utf8 |
Files: | files | file ages | folders |
SHA3-256: |
73a5f54231e9f6ad8f013df3987ea48c |
User & Date: | larrybr 2023-04-14 19:56:32.111 |
Context
2023-04-14
| ||
21:23 | Set CLI -utf8 option and build with line-editing package to be mutually exclusive. Integration of console-invasive UTF-8 handling with line-editing takeover of console may come later. (check-in: 047344a915 user: larrybr tags: cli-utf8) | |
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) | |
Changes
Changes to src/shell.c.in.
︙ | ︙ | |||
585 586 587 588 589 590 591 | } } return dynPrompt.dynamicPrompt; } #endif /* !defined(SQLITE_OMIT_DYNAPROMPT) */ #if (defined(_WIN32) || defined(WIN32)) && !defined(SQLITE_SHELL_FIDDLE) | > > | | | | > | < | | > | > | | | | < > | > | > | | > > | > | > > | > > > > > > > > > > > > > > > > > > | 585 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 611 612 613 614 615 616 617 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 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 | } } return dynPrompt.dynamicPrompt; } #endif /* !defined(SQLITE_OMIT_DYNAPROMPT) */ #if (defined(_WIN32) || defined(WIN32)) && !defined(SQLITE_SHELL_FIDDLE) /* Following variables are used for -utf8 operation. */ static int stdinEof = 0; /* EOF seen on console input */ static int infsMode; /* Input file stream mode upon shell start */ static UINT codePage = 0; /* Input code page upon shell start */ static HANDLE hConsoleIn = INVALID_HANDLE_VALUE; /* Console input handle */ static DWORD consoleMode; /* Console mode upon shell start */ /* ** 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){ hConsoleIn = GetStdHandle(STD_INPUT_HANDLE); if( isatty(0) && GetFileType(hConsoleIn)==FILE_TYPE_CHAR ){ if( !IsValidCodePage(CP_UTF8) ){ fprintf(stderr, "Cannot use UTF-8 code page.\n"); console_utf8 = 0; return; } codePage = GetConsoleCP(); SetConsoleCP(CP_UTF8); GetConsoleMode( hConsoleIn, &consoleMode); SetConsoleMode( hConsoleIn, consoleMode | ENABLE_LINE_INPUT ); infsMode = _setmode(_fileno(stdin), _O_U16TEXT); console_utf8 = 1; }else{ console_utf8 = 0; } } /* ** Undo the effects of instream_prepare(), if any. */ static void SQLITE_CDECL instream_restore(void){ if( console_utf8 && codePage!=0 &&hConsoleIn != INVALID_HANDLE_VALUE ){ _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){ if( fin==0 ) fin = stdin; if( fin==stdin && stdin_is_interactive && console_utf8 ){ # define SQLITE_IALIM 150 wchar_t wbuf[SQLITE_IALIM]; int lend = 0; int noc = 0; if( ncmax == 0 || stdinEof ) return 0; buf[0] = 0; while( noc < ncmax-7-1 && !lend ){ /* There is room for at least 2 more characters and a 0-terminator. */ int na = (ncmax > SQLITE_IALIM*4+1 + noc) ? SQLITE_IALIM : (ncmax-1 - noc)/4; # undef SQLITE_IALIM DWORD nbr = 0; BOOL bRC = ReadConsoleW(hConsoleIn, wbuf, na, &nbr, 0); if( !bRC || (noc==0 && nbr==0) ) return 0; if( nbr > 0 ){ int nmb = WideCharToMultiByte(CP_UTF8, WC_COMPOSITECHECK|WC_DEFAULTCHAR, wbuf,nbr, 0,0, 0, 0); if( nmb !=0 && noc+nmb <= ncmax ){ int iseg = noc; nmb = WideCharToMultiByte(CP_UTF8, WC_COMPOSITECHECK|WC_DEFAULTCHAR, wbuf,nbr, buf+noc,nmb, 0,0); noc += nmb; /* Fixup line-ends as coded by Windows for CR (or "Enter".)*/ if( noc > 0 ){ if( buf[noc-1]=='\n' ){ lend = 1; if( noc > 1 && buf[noc-2]=='\r' ){ buf[noc-2] = '\n'; --noc; } } } /* Check for ^Z (anywhere in line) too. */ while( iseg < noc ){ if( buf[iseg]==0x1a ){ 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; buf[noc] = 0; return buf; }else{ return fgets(buf, ncmax, fin); } } # define fgets(b,n,f) utf8_fgets(b,n,f) |
︙ | ︙ | |||
885 886 887 888 889 890 891 | n--; if( n>0 && zLine[n-1]=='\r' ) n--; zLine[n] = 0; break; } } #if defined(_WIN32) || defined(WIN32) | | | > | < < < < < < < | 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 | n--; if( n>0 && zLine[n-1]=='\r' ) n--; zLine[n] = 0; break; } } #if defined(_WIN32) || defined(WIN32) /* For interactive input on Windows systems, without -utf8, ** translate the multi-byte characterset characters into UTF-8. ** This is the translation that predates the -utf8 option. */ if( stdin_is_interactive && in==stdin && !console_utf8 ){ char *zTrans = sqlite3_win32_mbcs_to_utf8_v2(zLine, 0); if( zTrans ){ i64 nTrans = strlen(zTrans)+1; if( nTrans>nLine ){ zLine = realloc(zLine, nTrans); shell_check_oom(zLine); } memcpy(zLine, zTrans, nTrans); sqlite3_free(zTrans); } } #endif /* defined(_WIN32) || defined(WIN32) */ return zLine; } /* ** Retrieve a single line of input text. |
︙ | ︙ | |||
11815 11816 11817 11818 11819 11820 11821 | char **azCmd = 0; const char *zVfs = 0; /* Value of -vfs command-line option */ #if !SQLITE_SHELL_IS_UTF8 char **argvToFree = 0; int argcToFree = 0; #endif | < | 11838 11839 11840 11841 11842 11843 11844 11845 11846 11847 11848 11849 11850 11851 | char **azCmd = 0; const char *zVfs = 0; /* Value of -vfs command-line option */ #if !SQLITE_SHELL_IS_UTF8 char **argvToFree = 0; int argcToFree = 0; #endif setvbuf(stderr, 0, _IONBF, 0); /* Make sure stderr is unbuffered */ #ifdef SQLITE_SHELL_FIDDLE stdin_is_interactive = 0; stdout_is_console = 1; data.wasm.zDefaultDbName = "/fiddle.sqlite3"; #else stdin_is_interactive = isatty(0); |
︙ | ︙ | |||
12302 12303 12304 12305 12306 12307 12308 12309 12310 12311 12312 12313 12314 12315 | } data.cMode = data.mode; } #if (defined(_WIN32) || defined(WIN32)) && !defined(SQLITE_SHELL_FIDDLE) if( console_utf8 && stdin_is_interactive ){ instream_prepare(); }else{ console_utf8 = 0; } #endif if( !readStdin ){ /* Run all arguments that do not begin with '-' as if they were separate ** command-line inputs, except for the argToSkip argument which contains | > | 12324 12325 12326 12327 12328 12329 12330 12331 12332 12333 12334 12335 12336 12337 12338 | } data.cMode = data.mode; } #if (defined(_WIN32) || defined(WIN32)) && !defined(SQLITE_SHELL_FIDDLE) if( console_utf8 && stdin_is_interactive ){ instream_prepare(); }else{ setBinaryMode(stdin, 0); console_utf8 = 0; } #endif if( !readStdin ){ /* Run all arguments that do not begin with '-' as if they were separate ** command-line inputs, except for the argToSkip argument which contains |
︙ | ︙ |