Skip to content

Commit

Permalink
Revert "MDEV-26713 Windows - improve utf8 support for command line to…
Browse files Browse the repository at this point in the history
…ols"

This reverts commit several commits pushed by mistake.
  • Loading branch information
vaintroub committed Nov 19, 2021
1 parent 220dc1f commit 0102732
Show file tree
Hide file tree
Showing 25 changed files with 142 additions and 655 deletions.
126 changes: 25 additions & 101 deletions client/mysql.cc
Expand Up @@ -88,7 +88,9 @@ extern "C" {
#endif /* defined(HAVE_CURSES_H) && defined(HAVE_TERM_H) */

#undef bcmp // Fix problem with new readline
#if !defined(_WIN32)
#if defined(_WIN32)
#include <conio.h>
#else
# ifdef __APPLE__
# include <editline/readline.h>
# else
Expand All @@ -102,101 +104,6 @@ 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)
Expand Down Expand Up @@ -1812,10 +1719,8 @@ 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"
IF_WIN(", codepage %u",) "\n", my_progname, VER,
MYSQL_SERVER_VERSION, SYSTEM_TYPE, MACHINE_TYPE,SOURCE_REVISION,
IF_WIN(GetConsoleCP(),));
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);
#endif

if (version)
Expand Down Expand Up @@ -2210,7 +2115,26 @@ static int read_and_execute(bool interactive)

#if defined(_WIN32)
tee_fputs(prompt, stdout);
line= win_readline();
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();
#else
if (opt_outfile)
fputs(prompt, OUTFILE);
Expand Down
4 changes: 2 additions & 2 deletions cmake/os/Windows.cmake
Expand Up @@ -60,8 +60,8 @@ ENDIF()

ADD_DEFINITIONS(-D_CRT_SECURE_NO_DEPRECATE)
ADD_DEFINITIONS(-D_WIN32_WINNT=0x0A00)
# We do not want the windows.h , or winsvc.h macros min/max
ADD_DEFINITIONS(-DNOMINMAX -DNOSERVICE)
# We do not want the windows.h macros min/max
ADD_DEFINITIONS(-DNOMINMAX)
# Speed up build process excluding unused header files
ADD_DEFINITIONS(-DWIN32_LEAN_AND_MEAN)

Expand Down
5 changes: 0 additions & 5 deletions cmake/win_compatibility.manifest
Expand Up @@ -19,9 +19,4 @@

</application>
</compatibility>
<application>
<windowsSettings>
<activeCodePage xmlns="http://schemas.microsoft.com/SMI/2019/WindowsSettings">UTF-8</activeCodePage>
</windowsSettings>
</application>
</asmv1:assembly>
8 changes: 0 additions & 8 deletions include/my_global.h
Expand Up @@ -29,14 +29,6 @@
#pragma GCC poison __WIN__
#endif

#if defined(_MSC_VER)
/*
Following functions have bugs, when used with UTF-8 active codepage.
#include <winservice.h> will use the non-buggy wrappers
*/
#pragma deprecated("CreateServiceA", "OpenServiceA", "ChangeServiceConfigA")
#endif

/*
InnoDB depends on some MySQL internals which other plugins should not
need. This is because of InnoDB's foreign key support, "safe" binlog
Expand Down
2 changes: 1 addition & 1 deletion mysql-test/main/charset_client_win.test
@@ -1,2 +1,2 @@
--source include/windows.inc
--exec set MARIADB_DISABLE_UTF8_CONSOLE=1 && chcp 1257 > NUL && $MYSQL --default-character-set=auto -e "select @@character_set_client"
--exec chcp 1257 > NUL && $MYSQL --default-character-set=auto -e "select @@character_set_client"
2 changes: 0 additions & 2 deletions mysql-test/main/charset_client_win_utf8mb4.result

This file was deleted.

2 changes: 0 additions & 2 deletions mysql-test/main/charset_client_win_utf8mb4.test

This file was deleted.

File renamed without changes.
@@ -1,3 +1,5 @@
# UTF8 parameters to mysql client do not work on Windows
--source include/not_windows.inc
--source include/not_embedded.inc

#
Expand Down
17 changes: 0 additions & 17 deletions mysql-test/suite.pm
Expand Up @@ -87,23 +87,6 @@ sub skip_combinations {
$skip{'main/ssl_verify_ip.test'} = 'x509v3 support required'
unless $openssl_ver ge "1.0.2";

sub utf8_command_line_ok() {
if (IS_WINDOWS) {
# Can use UTF8 on command line since Windows 10 1903 (10.0.18362)
my($os_name, $os_major, $os_minor, $os_build, $os_id) = Win32::GetOSVersion();
if($os_major lt 10){
return 0;
} elsif($os_major gt 10 or $os_minor gt 0 or $os_build ge 18362) {
return 1;
}
return 0;
}
return 1;
}

$skip{'main/charset_client_win_utf8mb4.test'} =
$skip{'main/grant_utf8_cli.test'} = 'No utf8 command line support'
unless utf8_command_line_ok();

%skip;
}
Expand Down
2 changes: 1 addition & 1 deletion mysys/charset.c
Expand Up @@ -1393,7 +1393,7 @@ static const MY_CSET_OS_NAME charsets[] =
#ifdef UNCOMMENT_THIS_WHEN_WL_WL_4024_IS_DONE
{"cp54936", "gb18030", my_cs_exact},
#endif
{"cp65001", "utf8mb4", my_cs_exact},
{"cp65001", "utf8", my_cs_exact},

#else /* not Windows */

Expand Down
36 changes: 15 additions & 21 deletions mysys/get_password.c
Expand Up @@ -62,40 +62,34 @@

char *get_tty_password(const char *opt_message)
{
wchar_t wbuf[80];
char to[80*3]; /* there is at most 3 bytes per wchar, in any codepage */
wchar_t *pos=wbuf,*end=wbuf + array_elements(wbuf)-1;
char to[80];
char *pos=to,*end=to+sizeof(to)-1;
DBUG_ENTER("get_tty_password");
_cputs(opt_message ? opt_message : "Enter password: ");
for (;;)
{
int wc;
wc=_getwch();
if (wc == '\b' || wc == 127)
char tmp;
tmp=_getch();
if (tmp == '\b' || (int) tmp == 127)
{
if (pos != wbuf)
if (pos != to)
{
_cputs("\b \b");
pos--;
continue;
_cputs("\b \b");
pos--;
continue;
}
}
if (wc == '\n' || wc == '\r' || wc == 3 || pos == end)
if (tmp == '\n' || tmp == '\r' || tmp == 3)
break;
if (iswcntrl(wc))
if (iscntrl(tmp) || pos == end)
continue;

/* Do not print '*' for half-unicode char(high surrogate)*/
if (wc < 0xD800 || wc > 0xDBFF)
{
_cputs("*");
}
*(pos++)= (wchar_t)wc;
_cputs("*");
*(pos++) = tmp;
}
while (pos != to && isspace(pos[-1]) == ' ')
pos--; /* Allow dummy space at end */
*pos=0;
_cputs("\n");
if (!WideCharToMultiByte(GetConsoleCP(), 0 , wbuf , -1 , to, sizeof(to), NULL, NULL))
to[0]=0;
DBUG_RETURN(my_strdup(PSI_INSTRUMENT_ME, to,MYF(MY_FAE)));
}

Expand Down
51 changes: 4 additions & 47 deletions mysys/my_getopt.c
Expand Up @@ -38,7 +38,7 @@ static double getopt_double(char *arg, const struct my_option *optp, int *err);
static void init_variables(const struct my_option *, init_func_p);
static void init_one_value(const struct my_option *, void *, longlong);
static void fini_one_value(const struct my_option *, void *, longlong);
static int setval(const struct my_option *, void *, char *, my_bool, const char *);
static int setval(const struct my_option *, void *, char *, my_bool);
static char *check_struct_option(char *cur_arg, char *key_name);

/*
Expand Down Expand Up @@ -133,48 +133,6 @@ double getopt_ulonglong2double(ulonglong v)
return u.dbl;
}

#ifdef _WIN32
/**
On Windows, if program is running in UTF8 mode, but some arguments are not UTF8.
This will mostly likely be a sign of old "ANSI" my.ini, and it is likely that
something will go wrong, e.g file access error.
*/
static void validate_value(const char *key, const char *value,
const char *filename)
{
MY_STRCOPY_STATUS status;
const struct charset_info_st *cs= &my_charset_utf8mb4_bin;
size_t len;
if (GetACP() != CP_UTF8)
return;
len= strlen(value);
if (!len)
return;
cs->cset->well_formed_char_length(cs, value, value + len, len, &status);
if (!status.m_well_formed_error_pos)
return;

if (filename && *filename)
{
my_getopt_error_reporter(WARNING_LEVEL,
"%s: invalid (non-UTF8) characters found for option '%s'"
" in file '%s'",
my_progname, key, filename);
}
else
{
DBUG_ASSERT(0);
my_getopt_error_reporter(
WARNING_LEVEL, "%s: invalid (non-UTF8) characters for option %s",
my_progname, key);
}
}
#else
#define validate_value(key, value, filename) (void)filename
#endif

/**
Handle command line options.
Sort options.
Expand Down Expand Up @@ -606,7 +564,7 @@ int handle_options(int *argc, char ***argv, const struct my_option *longopts,
}
}
if ((error= setval(optp, optp->value, argument,
set_maximum_value,filename)))
set_maximum_value)))
DBUG_RETURN(error);
if (get_one_option(optp, argument, filename))
DBUG_RETURN(EXIT_UNSPECIFIED_ERROR);
Expand Down Expand Up @@ -652,7 +610,7 @@ int handle_options(int *argc, char ***argv, const struct my_option *longopts,
continue;
}
if ((!option_is_autoset) &&
((error= setval(optp, value, argument, set_maximum_value,filename))) &&
((error= setval(optp, value, argument, set_maximum_value))) &&
!option_is_loose)
DBUG_RETURN(error);
if (get_one_option(optp, argument, filename))
Expand Down Expand Up @@ -753,7 +711,7 @@ static my_bool get_bool_argument(const struct my_option *opts,
*/

static int setval(const struct my_option *opts, void *value, char *argument,
my_bool set_maximum_value, const char *option_file)
my_bool set_maximum_value)
{
int err= 0, res= 0;
DBUG_ENTER("setval");
Expand Down Expand Up @@ -900,7 +858,6 @@ static int setval(const struct my_option *opts, void *value, char *argument,
goto ret;
};
}
validate_value(opts->name, argument, option_file);
DBUG_RETURN(0);

ret:
Expand Down

0 comments on commit 0102732

Please sign in to comment.