diff options
Diffstat (limited to 'client/mysql.cc')
-rw-r--r-- | client/mysql.cc | 126 |
1 files changed, 101 insertions, 25 deletions
diff --git a/client/mysql.cc b/client/mysql.cc index ee963b9220d..c41232d2185 100644 --- a/client/mysql.cc +++ b/client/mysql.cc @@ -88,9 +88,7 @@ extern "C" { #endif /* defined(HAVE_CURSES_H) && defined(HAVE_TERM_H) */ #undef bcmp // Fix problem with new readline -#if defined(_WIN32) -#include <conio.h> -#else +#if !defined(_WIN32) # ifdef __APPLE__ # include <editline/readline.h> # else @@ -104,6 +102,101 @@ extern "C" { #endif } + +#if defined(_WIN32) +/* + Set console mode for the whole duration of the client session. + + We need for input + - line input (i.e read lines from console) + - echo typed characters + - "cooked" mode, i.e we do not want to handle all keystrokes, + like DEL etc ourselves, yet. We might want handle keystrokes + in the future, to implement tab completion, and better + (multiline) history. + + Disable VT escapes for the output.We do not know what kind of escapes SELECT would return. +*/ +struct Console_mode +{ + HANDLE in= GetStdHandle(STD_INPUT_HANDLE); + HANDLE out= GetStdHandle(STD_OUTPUT_HANDLE); + DWORD mode_in=0; + DWORD mode_out=0; + + enum {STDIN_CHANGED = 1, STDOUT_CHANGED = 2}; + int changes=0; + + Console_mode() + { + if (in && in != INVALID_HANDLE_VALUE && GetConsoleMode(in, &mode_in)) + { + SetConsoleMode(in, ENABLE_ECHO_INPUT|ENABLE_LINE_INPUT|ENABLE_PROCESSED_INPUT); + changes |= STDIN_CHANGED; + } + + if (out && out != INVALID_HANDLE_VALUE && GetConsoleMode(out, &mode_out)) + { +#ifdef ENABLE_VIRTUAL_TERMINAL_INPUT + SetConsoleMode(out, mode_out & ~ENABLE_VIRTUAL_TERMINAL_INPUT); + changes |= STDOUT_CHANGED; +#endif + } + } + + ~Console_mode() + { + if (changes & STDIN_CHANGED) + SetConsoleMode(in, mode_in); + + if(changes & STDOUT_CHANGED) + SetConsoleMode(out, mode_out); + } +}; + +static Console_mode my_conmode; + +#define MAX_CGETS_LINE_LEN 65535 +/** Read line from console in ANSI codepage, chomp EOL*/ +static char *win_readline() +{ + static wchar_t wstrbuf[MAX_CGETS_LINE_LEN]; + static char strbuf[MAX_CGETS_LINE_LEN*2]; + + DWORD nchars= 0; + SetLastError(0); + if (!ReadConsoleW(GetStdHandle(STD_INPUT_HANDLE), wstrbuf, MAX_CGETS_LINE_LEN-1, + &nchars, NULL)) + goto err; + if (nchars == 0 && GetLastError() == ERROR_OPERATION_ABORTED) + goto err; + + while (nchars > 0) + { + if (wstrbuf[nchars - 1] != '\n' && wstrbuf[nchars - 1] != '\r') + break; + wstrbuf[--nchars]= 0; + } + + wstrbuf[nchars]= 0; + if (nchars > 0) + { + int len = WideCharToMultiByte(GetConsoleCP(), 0, wstrbuf, nchars + 1, + strbuf, sizeof(strbuf),NULL, NULL); + if (len < 1) + strbuf[0]= 0; + } + else + { + strbuf[0]= 0; + } + return strbuf; +err: + return NULL; +} +#endif + + #ifdef HAVE_VIDATTR static int have_curses= 0; static void my_vidattr(chtype attrs) @@ -1719,8 +1812,10 @@ static void usage(int version) my_progname, VER, MYSQL_SERVER_VERSION, SYSTEM_TYPE, MACHINE_TYPE, readline, rl_library_version); #else - printf("%s Ver %s Distrib %s, for %s (%s), source revision %s\n", my_progname, VER, - MYSQL_SERVER_VERSION, SYSTEM_TYPE, MACHINE_TYPE,SOURCE_REVISION); + printf("%s Ver %s Distrib %s, for %s (%s), source revision %s" + IF_WIN(", codepage %u",) "\n", my_progname, VER, + MYSQL_SERVER_VERSION, SYSTEM_TYPE, MACHINE_TYPE,SOURCE_REVISION, + IF_WIN(GetConsoleCP(),)); #endif if (version) @@ -2115,26 +2210,7 @@ static int read_and_execute(bool interactive) #if defined(_WIN32) tee_fputs(prompt, stdout); - if (!tmpbuf.is_alloced()) - tmpbuf.alloc(65535); - tmpbuf.length(0); - buffer.length(0); - size_t clen; - do - { - line= my_cgets((char*)tmpbuf.ptr(), tmpbuf.alloced_length()-1, &clen); - buffer.append(line, clen); - /* - if we got buffer fully filled than there is a chance that - something else is still in console input buffer - */ - } while (tmpbuf.alloced_length() <= clen); - /* - An empty line is returned from my_cgets when there's error reading : - Ctrl-c for example - */ - if (line) - line= buffer.c_ptr(); + line= win_readline(); #else if (opt_outfile) fputs(prompt, OUTFILE); |