From: Eli Zaretskii Date: Sat, 17 Sep 2016 08:50:37 +0000 (+0300) Subject: Improve MinGW support in Readline X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=7f3c5ec870943f7f32c946ff9459dfd04fcb8e07;p=binutils-gdb.git Improve MinGW support in Readline These changes were already accepted upstream in Readline, but GDB did not yet import a newer Readline version. readline/Changelog.gdb: * util.c: Include rlshell.h. (_rl_tropen) [_WIN32 && !__CYGWIN__]: Open the trace file in the user's temporary directory. * tcap.h [HAVE_NCURSES_TERMCAP_H]: Include ncurses/termcap.h. * input.c (w32_isatty) [_WIN32 && !__CYGWIN__]: New function, to replace isatty that is not reliable enough on MS-Windows. (isatty) [_WIN32 && !__CYGWIN__]: Redirect to w32_isatty. (rl_getc): Call _getch, not getch, which could be an ncurses function when linked with ncurses, in which case getch will return EOF for any keystroke, because there's no curses window. * tilde.c (tilde_expand_word) [_WIN32]: * histfile.c (history_filename) [_WIN32]: Windows-specific environment variable to replace HOME if that is undefined. * funmap.c (default_funmap): Compile rl_paste_from_clipboard on all Windows platforms, not just Cygwin. * readline.h (rl_paste_from_clipboard): Include declaration for all Windows platforms. * display.c (insert_some_chars, delete_chars): Don't use the MinGW-specific code if linked with ncurses. * configure.in: * config.h.in: Support ncurses/termcap.h. The configure script was updated accordingly. * complete.c [_WIN32 && !__CYGWIN__]: Initialize _rl_completion_case_fold to 1. (printable_part, rl_filename_completion_function) [_WIN32 && !__CYGWIN__]: Handle the drive letter. --- diff --git a/readline/ChangeLog.gdb b/readline/ChangeLog.gdb index 43abd19e11c..91e1dbd11bc 100644 --- a/readline/ChangeLog.gdb +++ b/readline/ChangeLog.gdb @@ -1,3 +1,40 @@ +2016-09-17 Eli Zaretskii + + * util.c: Include rlshell.h. + (_rl_tropen) [_WIN32 && !__CYGWIN__]: Open the trace file in the + user's temporary directory. + + * tcap.h [HAVE_NCURSES_TERMCAP_H]: Include ncurses/termcap.h. + + * input.c (w32_isatty) [_WIN32 && !__CYGWIN__]: New function, to + replace isatty that is not reliable enough on MS-Windows. + (isatty) [_WIN32 && !__CYGWIN__]: Redirect to w32_isatty. + (rl_getc): Call _getch, not getch, which could be an ncurses + function when linked with ncurses, in which case getch will return + EOF for any keystroke, because there's no curses window. + + * tilde.c (tilde_expand_word) [_WIN32]: + * histfile.c (history_filename) [_WIN32]: Windows-specific + environment variable to replace HOME if that is undefined. + + * funmap.c (default_funmap): Compile rl_paste_from_clipboard on + all Windows platforms, not just Cygwin. + + * readline.h (rl_paste_from_clipboard): Include declaration for + all Windows platforms. + + * display.c (insert_some_chars, delete_chars): Don't use the + MinGW-specific code if linked with ncurses. + + * configure.in: + * config.h.in: Support ncurses/termcap.h. The configure script + was updated accordingly. + + * complete.c [_WIN32 && !__CYGWIN__]: Initialize + _rl_completion_case_fold to 1. + (printable_part, rl_filename_completion_function) + [_WIN32 && !__CYGWIN__]: Handle the drive letter. + 2014-12-30 Eli Zaretskii * complete.c (stat_char) [_WIN32]: Don't use 'access' and X_OK on diff --git a/readline/complete.c b/readline/complete.c index a5ce8039e50..5733d4e1a98 100644 --- a/readline/complete.c +++ b/readline/complete.c @@ -156,7 +156,8 @@ int _rl_complete_mark_symlink_dirs = 0; int _rl_print_completions_horizontally; /* Non-zero means that case is not significant in filename completion. */ -#if defined (__MSDOS__) && !defined (__DJGPP__) +#if defined (__MSDOS__) && !defined (__DJGPP__) \ + || (defined (_WIN32) && !defined (__CYGWIN__)) int _rl_completion_case_fold = 1; #else int _rl_completion_case_fold = 0; @@ -636,7 +637,7 @@ printable_part (pathname) return (pathname); temp = strrchr (pathname, '/'); -#if defined (__MSDOS__) +#if defined (__MSDOS__) || defined (_WIN32) if (temp == 0 && ISALPHA ((unsigned char)pathname[0]) && pathname[1] == ':') temp = pathname + 1; #endif @@ -2186,7 +2187,7 @@ rl_filename_completion_function (text, state) temp = strrchr (dirname, '/'); -#if defined (__MSDOS__) +#if defined (__MSDOS__) || defined (_WIN32) /* special hack for //X/... */ if (dirname[0] == '/' && dirname[1] == '/' && ISALPHA ((unsigned char)dirname[2]) && dirname[3] == '/') temp = strrchr (dirname + 3, '/'); @@ -2197,7 +2198,7 @@ rl_filename_completion_function (text, state) strcpy (filename, ++temp); *temp = '\0'; } -#if defined (__MSDOS__) +#if defined (__MSDOS__) || (defined (_WIN32) && !defined (__CYGWIN__)) /* searches from current directory on the drive */ else if (ISALPHA ((unsigned char)dirname[0]) && dirname[1] == ':') { diff --git a/readline/config.h.in b/readline/config.h.in index 8560c4be9f3..86d86cfa3da 100644 --- a/readline/config.h.in +++ b/readline/config.h.in @@ -186,6 +186,9 @@ /* Define if you have the header file. */ #undef HAVE_TERMCAP_H +/* Define if you have the header file. */ +#undef HAVE_NCURSES_TERMCAP_H + /* Define if you have the header file. */ #undef HAVE_TERMIO_H diff --git a/readline/configure b/readline/configure index 09de45df5e4..249ab7bd3ef 100755 --- a/readline/configure +++ b/readline/configure @@ -5845,6 +5845,23 @@ if test "$TERMCAP_LIB" = "./lib/termcap/libtermcap.a"; then fi fi +if test "$TERMCAP_LIB" = "-lncurses"; then + +for ac_header in ncurses/termcap.h +do : + as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" +eval as_val=\$$as_ac_Header + if test "x$as_val" = x""yes; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + +fi for ac_header in wctype.h do : diff --git a/readline/configure.in b/readline/configure.in index b395af458f4..b6d7167fca9 100644 --- a/readline/configure.in +++ b/readline/configure.in @@ -198,6 +198,9 @@ if test "$TERMCAP_LIB" = "./lib/termcap/libtermcap.a"; then TERMCAP_LIB=-ltermcap #default fi fi +if test "$TERMCAP_LIB" = "-lncurses"; then + AC_CHECK_HEADERS(ncurses/termcap.h) +fi BASH_CHECK_MULTIBYTE diff --git a/readline/display.c b/readline/display.c index 7653d873197..90443057974 100644 --- a/readline/display.c +++ b/readline/display.c @@ -2374,7 +2374,7 @@ insert_some_chars (string, count, col) char *string; int count, col; { -#if defined (__MSDOS__) || defined (__MINGW32__) +#if defined (__MSDOS__) || (defined (__MINGW32__) && !defined (NCURSES_VERSION)) _rl_output_some_chars (string, count); #else /* DEBUGGING */ @@ -2426,7 +2426,7 @@ delete_chars (count) if (count > _rl_screenwidth) /* XXX */ return; -#if !defined (__MSDOS__) && !defined (__MINGW32__) +#if !defined (__MSDOS__) && !(defined (__MINGW32__) && !defined (NCURSES_VERSION)) if (_rl_term_DC && *_rl_term_DC) { char *buffer; diff --git a/readline/funmap.c b/readline/funmap.c index 86e375f60d0..e61d69f97c0 100644 --- a/readline/funmap.c +++ b/readline/funmap.c @@ -113,7 +113,7 @@ static const FUNMAP default_funmap[] = { { "non-incremental-reverse-search-history-again", rl_noninc_reverse_search_again }, { "old-menu-complete", rl_old_menu_complete }, { "overwrite-mode", rl_overwrite_mode }, -#ifdef __CYGWIN__ +#ifdef _WIN32 { "paste-from-clipboard", rl_paste_from_clipboard }, #endif { "possible-completions", rl_possible_completions }, diff --git a/readline/histfile.c b/readline/histfile.c index 30a618247f1..fffeb3fd319 100644 --- a/readline/histfile.c +++ b/readline/histfile.c @@ -123,6 +123,10 @@ history_filename (filename) return (return_val); home = sh_get_env_value ("HOME"); +#ifdef _WIN32 + if (!home) + home = sh_get_env_value ("APPDATA"); +#endif if (home == 0) { diff --git a/readline/input.c b/readline/input.c index 7c74c995089..e35277fd2df 100644 --- a/readline/input.c +++ b/readline/input.c @@ -86,6 +86,36 @@ static int ibuffer_space PARAMS((void)); static int rl_get_char PARAMS((int *)); static int rl_gather_tyi PARAMS((void)); +#if defined (_WIN32) && !defined (__CYGWIN__) + +/* 'isatty' in the Windows runtime returns non-zero for every + character device, including the null device. Repair that. */ +#include +#define WIN32_LEAN_AND_MEAN 1 +#include + +int w32_isatty (int fd) +{ + if (_isatty(fd)) + { + HANDLE h = (HANDLE) _get_osfhandle (fd); + DWORD ignored; + + if (h == INVALID_HANDLE_VALUE) + { + errno = EBADF; + return 0; + } + if (GetConsoleMode (h, &ignored) != 0) + return 1; + } + errno = ENOTTY; + return 0; +} + +#define isatty(x) w32_isatty(x) +#endif + /* **************************************************************** */ /* */ /* Character Input Buffering */ @@ -465,8 +495,10 @@ rl_getc (stream) RL_CHECK_SIGNALS (); #if defined (__MINGW32__) + /* Use _getch to make sure we call the function from MS runtime, + even if some curses library is linked in. */ if (isatty (fileno (stream))) - return (getch ()); + return (_getch ()); #endif result = read (fileno (stream), &c, sizeof (unsigned char)); diff --git a/readline/kill.c b/readline/kill.c index 1a78783f9aa..ce26d0a6105 100644 --- a/readline/kill.c +++ b/readline/kill.c @@ -657,7 +657,7 @@ rl_yank_last_arg (count, key) } /* A special paste command for users of Cygnus's cygwin32. */ -#if defined (__CYGWIN__) +#if defined (_WIN32) #include int diff --git a/readline/readline.h b/readline/readline.h index 0de168cdd6c..97727460b46 100644 --- a/readline/readline.h +++ b/readline/readline.h @@ -172,8 +172,8 @@ extern int rl_yank PARAMS((int, int)); extern int rl_yank_pop PARAMS((int, int)); extern int rl_yank_nth_arg PARAMS((int, int)); extern int rl_yank_last_arg PARAMS((int, int)); -/* Not available unless __CYGWIN__ is defined. */ -#ifdef __CYGWIN__ +/* Not available unless _WIN32 is defined. */ +#ifdef _WIN32 extern int rl_paste_from_clipboard PARAMS((int, int)); #endif diff --git a/readline/tcap.h b/readline/tcap.h index 9d09b7a9cfc..dbc1789a8cb 100644 --- a/readline/tcap.h +++ b/readline/tcap.h @@ -31,6 +31,8 @@ # include "rltty.h" # endif # include +#elif defined (HAVE_NCURSES_TERMCAP_H) +# include #else /* On Solaris2, sys/types.h #includes sys/reg.h, which #defines PC. diff --git a/readline/tilde.c b/readline/tilde.c index 1c53a457d46..d4c1da9e68d 100644 --- a/readline/tilde.c +++ b/readline/tilde.c @@ -360,6 +360,10 @@ tilde_expand_word (filename) { /* Prefix $HOME to the rest of the string. */ expansion = sh_get_env_value ("HOME"); +#ifdef _WIN32 + if (!expansion) + expansion = sh_get_env_value ("APPDATA"); +#endif /* If there is no HOME variable, look up the directory in the password database. */ diff --git a/readline/util.c b/readline/util.c index 321dee23560..d402fce842c 100644 --- a/readline/util.c +++ b/readline/util.c @@ -55,6 +55,7 @@ #include "rlprivate.h" #include "xmalloc.h" +#include "rlshell.h" /* **************************************************************** */ /* */ @@ -507,7 +508,17 @@ _rl_tropen () if (_rl_tracefp) fclose (_rl_tracefp); +#if defined (_WIN32) && !defined (__CYGWIN__) + /* Windows doesn't have /var/tmp, so open the trace file in the + user's temporary directory instead. */ + sprintf (fnbuf, "%s/rltrace.%ld", + (sh_get_env_value ("TEMP") + ? sh_get_env_value ("TEMP") + : "."), + getpid()); +#else sprintf (fnbuf, "/var/tmp/rltrace.%ld", getpid()); +#endif unlink(fnbuf); _rl_tracefp = fopen (fnbuf, "w+"); return _rl_tracefp != 0;