PATCH: MinGW readline -- revised

Mark Mitchell
2005-07-19T00:11:22Z

This patch is the revised GDB-on-MinGW bit.

There are three subparts:

1) Minor bit-rot in remote-sim.c and ser-tcp.c on MinGW. In
particular, SIGTRAP is being used unconditionally in the former,
and the MinGW definition of "close" (in terms of "closesocket")
needs to be a function-like macro, so as to avoid confusion in
code like "ops->close = net_close".

2) On the GDB side, I've added a win32-termcap.c file that contains
the stub termcap implementation. There seemed to be no consensus
that it belongs in libiberty, so I've submitted it here. I'd
really appreciate being able to check this in; if it's later
decided that it's wanted in libiberty, I'll happily move it.

3) On the readline side, I've backported the MinGW changes that will
be in readline 5.1.

OK?

--
Mark Mitchell
CodeSourcery, LLC
mark@codesourcery.com

2005-07-18 Mark Mitchell <mark@codesourcery.com>

* configure.ac: On MinGW, do not require a termcap library, and
use win32-termcap.c.
* configure: Regenerated.
* win32-termcap.c: New file.

* remote-sim.c (gdbsim_wait): Do not use SIGTRAP if not
defined.

* ser-tcp.c (close): Define as a function-like macro on MinGW.

2005-07-18 Mark Mitchell <mark@codesourcery.com>

* input.c (rl_getc): Use getch to read console input on
Windows.
* readline.c (bind_arrow_keys_internal): Translate
Windows keysequences into POSIX key sequences.
* rldefs.h (NO_TTY_DRIVER): Define on MinGW.
* rltty.c: Conditionalize on NO_TTY_DRIVER throughout.

Index: gdb/configure.ac
===================================================================
RCS file: /cvs/src/src/gdb/configure.ac,v
retrieving revision 1.23
diff -c -5 -p -r1.23 configure.ac
*** gdb/configure.ac 3 Jul 2005 16:05:07 -0000 1.23
--- gdb/configure.ac 19 Jul 2005 00:05:26 -0000
*************** case $host_os in
*** 330,339 ****
--- 330,343 ----
ac_cv_search_tgetent="../libtermcap/libtermcap.a"
fi ;;
go32* | *djgpp*)
ac_cv_search_tgetent="none required"
;;
+ *mingw32*)
+ ac_cv_search_tgetent="none required"
+ CONFIG_OBS="$CONFIG_OBS win32-termcap.o"
+ ;;
esac

# These are the libraries checked by Readline.
AC_SEARCH_LIBS(tgetent, [termcap tinfo curses ncurses])

Index: gdb/remote-sim.c
===================================================================
RCS file: /cvs/src/src/gdb/remote-sim.c,v
retrieving revision 1.49
diff -c -5 -p -r1.49 remote-sim.c
*** gdb/remote-sim.c 19 Jun 2005 20:08:37 -0000 1.49
--- gdb/remote-sim.c 18 Jul 2005 23:59:21 -0000
*************** gdbsim_wait (ptid_t ptid, struct target_
*** 692,702 ****
--- 692,704 ----
{
case SIGABRT:
quit ();
break;
case SIGINT:
+ #ifdef SIGTRAP
case SIGTRAP:
+ #endif
default:
status->kind = TARGET_WAITKIND_STOPPED;
/* The signal in sigrc is a host signal. That probably
should be fixed. */
status->value.sig = target_signal_from_host (sigrc);
Index: gdb/ser-tcp.c
===================================================================
RCS file: /cvs/src/src/gdb/ser-tcp.c,v
retrieving revision 1.23
diff -c -5 -p -r1.23 ser-tcp.c
*** gdb/ser-tcp.c 13 Jun 2005 21:31:57 -0000 1.23
--- gdb/ser-tcp.c 18 Jul 2005 23:59:21 -0000
***************
*** 37,47 ****
#include <sys/time.h>

#ifdef USE_WIN32API
#include <winsock2.h>
#define ETIMEDOUT WSAETIMEDOUT
! #define close closesocket
#define ioctl ioctlsocket
#else
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
--- 37,47 ----
#include <sys/time.h>

#ifdef USE_WIN32API
#include <winsock2.h>
#define ETIMEDOUT WSAETIMEDOUT
! #define close(fd) closesocket (fd)
#define ioctl ioctlsocket
#else
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
Index: gdb/win32-termcap.c
===================================================================
RCS file: gdb/win32-termcap.c
diff -N gdb/win32-termcap.c
*** /dev/null 1 Jan 1970 00:00:00 -0000
--- gdb/win32-termcap.c 18 Jul 2005 23:59:21 -0000
***************
*** 0 ****
--- 1,65 ----
+ /* Win32 termcap emulation.
+
+ Copyright 2005 Free Software Foundation, Inc.
+
+ Contributed by CodeSourcery, LLC.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without eve nthe implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St., Fifth Floor, Boston, MA
+ 02110-1301, USA. */
+
+ #include <stdlib.h>
+
+ /* Each of the files below is a minimal implementation of the standard
+ termcap function with the same name, suitable for use in a Windows
+ console window. */
+
+ int
+ tgetent (char *buffer, char *termtype)
+ {
+ return -1;
+ }
+
+ int
+ tgetnum (char *name)
+ {
+ return -1;
+ }
+
+ int
+ tgetflag (char *name)
+ {
+ return -1;
+ }
+
+ char *
+ tgetstr (char *name, char **area)
+ {
+ return NULL;
+ }
+
+ int
+ tputs (char *string, int nlines, int (*outfun) ())
+ {
+ while (*string)
+ outfun (*string++);
+ }
+
+ char *
+ tgoto (const char *cap, int col, int row)
+ {
+ return NULL;
+ }
Index: readline/input.c
===================================================================
RCS file: /cvs/src/src/readline/input.c,v
retrieving revision 1.5
diff -c -5 -p -r1.5 input.c
*** readline/input.c 8 Dec 2002 22:31:37 -0000 1.5
--- readline/input.c 18 Jul 2005 23:59:21 -0000
*************** rl_getc (stream)
*** 422,431 ****
--- 422,438 ----
int result;
unsigned char c;

while (1)
{
+ #ifdef __MINGW32__
+ /* On Windows, use a special routine to read a single character
+ from the console. (Otherwise, no characters are available
+ until the user hits the return key.) */
+ if (isatty (fileno (stream)))
+ return getch ();
+ #endif
result = read (fileno (stream), &c, sizeof (unsigned char));

if (result == sizeof (unsigned char))
return (c);

Index: readline/readline.c
===================================================================
RCS file: /cvs/src/src/readline/readline.c,v
retrieving revision 1.7
diff -c -5 -p -r1.7 readline.c
*** readline/readline.c 27 Jan 2004 22:25:15 -0000 1.7
--- readline/readline.c 18 Jul 2005 23:59:21 -0000
*************** bind_arrow_keys_internal (map)
*** 866,875 ****
--- 866,891 ----
_rl_bind_if_unbound ("\033[0B", rl_backward_char);
_rl_bind_if_unbound ("\033[0C", rl_forward_char);
_rl_bind_if_unbound ("\033[0D", rl_get_next_history);
#endif

+ #ifdef __MINGW32__
+ /* Under Windows, when an extend key (like an arrow key) is
+ pressed, getch() will return 340 (octal) followed by a code for
+ the extended key. We use macros to transform those into the
+ normal ANSI terminal sequences for these keys. */
+
+ /* Up arrow. */
+ rl_macro_bind ("\340H", "\033[A", map);
+ /* Left arrow. */
+ rl_macro_bind ("\340K", "\033[D", map);
+ /* Right arrow. */
+ rl_macro_bind ("\340M", "\033[C", map);
+ /* Down arrow. */
+ rl_macro_bind ("\340P", "\033[B", map);
+ #endif
+
_rl_bind_if_unbound ("\033[A", rl_get_previous_history);
_rl_bind_if_unbound ("\033[B", rl_get_next_history);
_rl_bind_if_unbound ("\033[C", rl_forward_char);
_rl_bind_if_unbound ("\033[D", rl_backward_char);
_rl_bind_if_unbound ("\033[H", rl_beg_of_line);
Index: readline/rldefs.h
===================================================================
RCS file: /cvs/src/src/readline/rldefs.h,v
retrieving revision 1.4
diff -c -5 -p -r1.4 rldefs.h
*** readline/rldefs.h 8 Dec 2002 22:31:37 -0000 1.4
--- readline/rldefs.h 18 Jul 2005 23:59:21 -0000
***************
*** 30,40 ****
# include "config.h"
#endif

#include "rlstdc.h"

! #if defined (_POSIX_VERSION) && !defined (TERMIOS_MISSING)
# define TERMIOS_TTY_DRIVER
#else
# if defined (HAVE_TERMIO_H)
# define TERMIO_TTY_DRIVER
# else
--- 30,42 ----
# include "config.h"
#endif

#include "rlstdc.h"

! #if defined (__MINGW32__)
! # define NO_TTY_DRIVER
! #elif defined (_POSIX_VERSION) && !defined (TERMIOS_MISSING)
# define TERMIOS_TTY_DRIVER
#else
# if defined (HAVE_TERMIO_H)
# define TERMIO_TTY_DRIVER
# else
Index: readline/rltty.c
===================================================================
RCS file: /cvs/src/src/readline/rltty.c,v
retrieving revision 1.6
diff -c -5 -p -r1.6 rltty.c
*** readline/rltty.c 8 Dec 2002 22:31:37 -0000 1.6
--- readline/rltty.c 18 Jul 2005 23:59:21 -0000
*************** set_winsize (tty)
*** 150,160 ****
if (ioctl (tty, TIOCGWINSZ, &w) == 0)
(void) ioctl (tty, TIOCSWINSZ, &w);
#endif /* TIOCGWINSZ */
}

! #if defined (NEW_TTY_DRIVER)

/* Values for the `flags' field of a struct bsdtty. This tells which
elements of the struct bsdtty have been fetched from the system and
are valid. */
#define SGTTY_SET 0x01
--- 150,162 ----
if (ioctl (tty, TIOCGWINSZ, &w) == 0)
(void) ioctl (tty, TIOCSWINSZ, &w);
#endif /* TIOCGWINSZ */
}

! #if defined (NO_TTY_DRIVER)
! /* Nothing */
! #elif defined (NEW_TTY_DRIVER)

/* Values for the `flags' field of a struct bsdtty. This tells which
elements of the struct bsdtty have been fetched from the system and
are valid. */
#define SGTTY_SET 0x01
*************** prepare_terminal_settings (meta_flag, ol
*** 630,639 ****
--- 632,657 ----

#endif /* TERMIOS_TTY_DRIVER && _POSIX_VDISABLE */
}
#endif /* NEW_TTY_DRIVER */

+ /* Put the terminal in CBREAK mode so that we can detect key
+ presses. */
+ #if defined (NO_TTY_DRIVER)
+ void
+ rl_prep_terminal (meta_flag)
+ int meta_flag;
+ {
+ readline_echoing_p = 1;
+ }
+
+ void
+ rl_deprep_terminal ()
+ {
+ }
+
+ #else /* ! NO_TTY_DRIVER */
/* Put the terminal in CBREAK mode so that we can detect key presses. */
void
rl_prep_terminal (meta_flag)
int meta_flag;
{
*************** rl_deprep_terminal ()
*** 704,713 ****
--- 722,732 ----
terminal_prepped = 0;
RL_UNSETSTATE(RL_STATE_TERMPREPPED);

release_sigint ();
}
+ #endif /* !NO_TTY_DRIVER */
\f
/* **************************************************************** */
/* */
/* Bogus Flow Control */
/* */
*************** rl_deprep_terminal ()
*** 715,724 ****
--- 734,747 ----

int
rl_restart_output (count, key)
int count, key;
{
+ #if defined (__MINGW32__)
+ return 0;
+ #else /* !__MING32__ */
+
int fildes = fileno (rl_outstream);
#if defined (TIOCSTART)
#if defined (apollo)
ioctl (&fildes, TIOCSTART, 0);
#else
*************** rl_restart_output (count, key)
*** 742,757 ****
--- 765,785 ----
# endif /* TCXONC */
# endif /* !TERMIOS_TTY_DRIVER */
#endif /* !TIOCSTART */

return 0;
+ #endif /* !__MINGW32__ */
}

int
rl_stop_output (count, key)
int count, key;
{
+ #if defined (__MINGW32__)
+ return 0;
+ #else
+
int fildes = fileno (rl_instream);

#if defined (TIOCSTOP)
# if defined (apollo)
ioctl (&fildes, TIOCSTOP, 0);
*************** rl_stop_output (count, key)
*** 770,779 ****
--- 798,808 ----
# endif /* TCXONC */
# endif /* !TERMIOS_TTY_DRIVER */
#endif /* !TIOCSTOP */

return 0;
+ #endif /* !__MINGW32__ */
}

/* **************************************************************** */
/* */
/* Default Key Bindings */
*************** rl_stop_output (count, key)
*** 784,793 ****
--- 813,823 ----
in KMAP. Should be static, now that we have rl_tty_set_default_bindings. */
void
rltty_set_default_bindings (kmap)
Keymap kmap;
{
+ #if !defined (NO_TTY_DRIVER)
TIOTYPE ttybuff;
int tty = fileno (rl_instream);

#if defined (NEW_TTY_DRIVER)

*************** rltty_set_default_bindings (kmap)
*** 842,851 ****
--- 872,882 ----
# if defined (VWERASE) && defined (TERMIOS_TTY_DRIVER)
SET_SPECIAL (VWERASE, rl_unix_word_rubout);
# endif /* VWERASE && TERMIOS_TTY_DRIVER */
}
#endif /* !NEW_TTY_DRIVER */
+ #endif
}

/* New public way to set the system default editing chars to their readline
equivalents. */
void
*************** rl_tty_set_default_bindings (kmap)
*** 855,865 ****
rltty_set_default_bindings (kmap);
}

#if defined (HANDLE_SIGNALS)

! #if defined (NEW_TTY_DRIVER)
int
_rl_disable_tty_signals ()
{
return 0;
}
--- 886,896 ----
rltty_set_default_bindings (kmap);
}

#if defined (HANDLE_SIGNALS)

! #if defined (NEW_TTY_DRIVER) || defined (NO_TTY_DRIVER)
int
_rl_disable_tty_signals ()
{
return 0;
}