Improve MinGW support in Readline
authorEli Zaretskii <eliz@gnu.org>
Sat, 17 Sep 2016 08:50:37 +0000 (11:50 +0300)
committerEli Zaretskii <eliz@gnu.org>
Sat, 17 Sep 2016 08:50:37 +0000 (11:50 +0300)
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.

14 files changed:
readline/ChangeLog.gdb
readline/complete.c
readline/config.h.in
readline/configure
readline/configure.in
readline/display.c
readline/funmap.c
readline/histfile.c
readline/input.c
readline/kill.c
readline/readline.h
readline/tcap.h
readline/tilde.c
readline/util.c

index 43abd19e11ca9b9e194cb255265dfdf5282f5238..91e1dbd11bccdeceef4239af79caec60525d0ea1 100644 (file)
@@ -1,3 +1,40 @@
+2016-09-17  Eli Zaretskii  <eliz@gnu.org>
+
+       * 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  <eliz@gnu.org>
 
        * complete.c (stat_char) [_WIN32]: Don't use 'access' and X_OK on
index a5ce8039e5010ca9ce5193941f2ab386a87f39c2..5733d4e1a98f98fa428eeb4ae338ae2aa4983b68 100644 (file)
@@ -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] == ':')
         {
index 8560c4be9f3bb6cbd1dbf1488716f3d6f774e1f3..86d86cfa3da306bb98d330f2d8db728bdd4edfc9 100644 (file)
 /* Define if you have the <termcap.h> header file.  */
 #undef HAVE_TERMCAP_H
 
+/* Define if you have the <ncurses/termcap.h> header file.  */
+#undef HAVE_NCURSES_TERMCAP_H
+
 /* Define if you have the <termio.h> header file.  */
 #undef HAVE_TERMIO_H
 
index 09de45df5e404621d3ea16fee7e375477b5de9f2..249ab7bd3ef7226a8c5e4fdd4b997712df6e83cd 100755 (executable)
@@ -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 :
index b395af458f4d18fdfefdb45e77066c8c7f8e5d8b..b6d7167fca9acecdcab4400a6207af5e51012b61 100644 (file)
@@ -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
 
index 7653d8731974d9931c2f9aa698dc857a9a0108da..90443057974d4e5f6bff7343fd3016a96fd9c554 100644 (file)
@@ -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;
index 86e375f60d03f0f96b7253303ee38704c9572728..e61d69f97c05974ab33e30ad094a6b4d1c40884a 100644 (file)
@@ -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 },
index 30a618247f1ec8a7be1c9202ae84224c7e8d5d5e..fffeb3fd319e1b5328fd3c1c0f2cf639c9d2d588 100644 (file)
@@ -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)
     {
index 7c74c99508911f98889eec9c176f212a52c2766a..e35277fd2df13fb78b512eaac8a575778fcbade7 100644 (file)
@@ -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 <io.h>
+#define WIN32_LEAN_AND_MEAN 1
+#include <windows.h>
+
+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));
 
index 1a78783f9aac29bc5c60b92d2ef6d217bd5ba0c1..ce26d0a6105f4d43984a30f92d02ed09231f1278 100644 (file)
@@ -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 <windows.h>
 
 int
index 0de168cdd6c0b3fd93ffbd24c771ff0bcf24b27b..97727460b46b1e222d010bc05dce79734351c83d 100644 (file)
@@ -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
 
index 9d09b7a9cfcd7f4bb8401cf7ca429ec2514e2c15..dbc1789a8cbe65102f85ca7692884e914e82219f 100644 (file)
@@ -31,6 +31,8 @@
 #    include "rltty.h"
 #  endif
 #  include <termcap.h>
+#elif defined (HAVE_NCURSES_TERMCAP_H)
+#  include <ncurses/termcap.h>
 #else
 
 /* On Solaris2, sys/types.h #includes sys/reg.h, which #defines PC.
index 1c53a457d46ba17e3215f65476e3771a129de8e0..d4c1da9e68d0a599e176ab8eabf8bac40ac4ffc9 100644 (file)
@@ -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. */
index 321dee23560de88fd4856dcadc76f22e058ec3a2..d402fce842c941737a3ff3b24cffa50d592c8b62 100644 (file)
@@ -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;