#  DJGPP specific changes to readline used by the DJGPP port of gdb.


2019-02-24  Juan Manuel Guerrero  <juan.guerrero@gmx.de>

	* bind.c [__MSDOS__, __DJGPP__]:  New macro HAVE_LFN_SUPPORT to
	determinate at run time if LFN support is available or not.  For MSDOS
	it always returns false.
	[__DJGPP__]:  Macro SYS_INPUTRC redifined to "/dev/env/DJDIR/etc/inputrc".
	(rl_read_init_file) [__MSDOS__]:  Use HAVE_LFN_SUPPORT to decide if
	".inputrc" is a valid file name for the file system used.  If not or
	if the file does not exists try "_inputrc" instead.
	(rl_translate_keyseq, rl_parse_and_bind, rl_function_dumper):  Pacify
	compiler.
	(rl_function_dumper):  Free allocated string.

	* complete.c [__MSDOS__]:  New macro IS_DIR_SEPARATOR.  For DOS/DJGPP
	it checks for slash and backslash as directory separotor.
	(printable_part):  Use IS_DIR_SEPARATOR instead of hard coded slash as
	directory separator.
	(_rl_find_completion_word) [__MSDOS__]:  Ignore colons.
	Pacify compiler.
	(make_quoted_replacement) [__MSDOS__]:  Do not allow ':' to be quoted
	in DOS-style filenames.
	(rl_username_completion_function):  For DJGPP deactivate MS-DOS specific
	//X/ hack.
	(rl_completion_matches, rl_username_completion_function):  Pacify
	compiler.

	* display.c [__MSDOS__]:  Include pc.h.
	(_rl_move_cursor_relative) [__MSDOS__]:  For MSDOS/DJGPP use putc
	instead of tputs.
	(_rl_move_vert) [__MSDOS__]:  For MSDOS/DJGPP use putc instead of
	tputs.
	(_rl_clear_screen):  Clear screen the DJGPP way.
	(_rl_clear_to_eol) [__MSDOS__]:  For DJGPP use putc instead of tputs.

	doc/hstech.texi:  DJGPP specific info added.

	doc/rluser.texi:  DJGPP specific info added.

	* examples/fileman.c (main):  Add int return type to main function.
	(command_generator):  Pacify compiler.
	(main):  Add int return type to main function.
	(initialize_readline):  Add void return type to function.
	(com_list):  Add int return type to function.
	(com_view):  Add int return type to function.
	(com_rename):  Add int return type to function.
	(com_stat):  Add int return type to function.
	(com_delete):  Add int return type to function.
	(com_help):  Add int return type to function.
	(com_cd):  Add int return type to function.
	(com_pwd):  Add int return type to function.
	(com_quit):  Add int return type to function.
	(too_dangerous):  Add void return type to function.

	* examples/histexamp.c (main):  Add int return type to main function.
	[HAVE_STDLIB_H]:  Include stdlib.h for free prototype.

	* examples/rl.c [HAVE_UNISTD_H]:  Include unistd.h for getopt prototype.

	* examples/rlcat.c (main):  Pacify compiler.

	* examples/rlevent.c [HAVE_UNISTD_H]:  Include unistd.h for sleep and
	getopt prototypes.

	* examples/rlversion.c (main):  Add int return type to main function.

	* examples/rltest.c:  Add int return type to main function.

	* terminal.c [__MSDOS__]:  Include pc.h.
	[__MSDOS__]:  For MSDOS/DJGPP do not define nor compile
	reset_default_bindings.
	(_rl_set_cursor):  No-op for DJGPP.
	[__MSDOS__]:  Reorder global variable and functions so that they are
	defined and compiled only if required for DJGPP/MSDOS.
	(_rl_init_terminal_io) [__MSDOS__, __DJGPP__]:  For DJGPP use its libc
	functions to get screen width and hight.  For MSDOS use hard coded values.
	Set _rl_term_* to values appropriate for DOS/DJGPP.
	(rl_get_termcap ):  No-op for MSDOS/DJGPP.

	* funmap.c [__DJGPP__]:  For DJGPP added entry for rl_paste_from_clipboard
	into default_funma array.

	* histexpand.c (get_history_event):  Pacify compiler.

	* histfile.c [__DJGPP__]:  Open files in binary mode.
	[__MSDOS__, __DJGPP__]:  New macro HAVE_LFN_SUPPORT to determinate at
	run time if LFN support is available or not.  For MSDOS it always
	returns false.  New macro FILE_EXISTS uses access to check if a file
	exists.
	(history_filename) [__MSDOS__]:  Use HAVE_LFN_SUPPORT to decide if
	".history" is a valid file name for the file system used.
	Use FILE_EXISTS to decide if ".history" or "_history" shall be used
	when LFN is available.

	* input.c (rl_read_key):  Pacify compiler.

	* kill.c [__DJGPP__]:  New function rl_paste_from_clipboard.  A special
	paste command to allow DJGPP users to paste from the Windows clipboard.

	* misc.c (_rl_revert_all_lines):  Pacify compiler.

	* readline.c [__DJGPP__]:  Include sys/exceptn.h.
	(readline_internal_charloop):  Define eof to -1.
	(readline_initialize_everything) [__DJGPP__]:  To bind tty characters
	to readline functions use __libc_termios_enable_function_and_arrow_keys.

	* readline.h [__DJGPP__]:  rl_paste_from_clipboard only available if it
	is DJGPP.

	* signals.c: [SIGWINCH]:  If SIGWINCH is not defined do not define the
	variables sigwinch_set_flag, sigwinch_set, sigwinch_oset, sigwinch_oldmask
	and sigwinch_blocked and do not compile the functions _rl_block_sigwinch
	and _rl_release_sigwinch.

	* tcap.h [__MSDOS__]:  Do not enable termcap support for MS-DOS.

	* tilde.c (tilde_expand):  Pacify compiler.

	* tminit.c:  Adjust for use with DJGPP 2.04.






diff -aprNU5 gdb-7.12.1.orig/readline/bind.c gdb-7.12.1/readline/bind.c
--- gdb-7.12.1.orig/readline/bind.c	2016-08-01 15:50:20 +0000
+++ gdb-7.12.1/readline/bind.c	2019-02-24 16:06:12 +0000
@@ -67,10 +67,24 @@ extern int errno;
 
 #if !defined (strchr) && !defined (__STDC__)
 extern char *strchr (), *strrchr ();
 #endif /* !strchr && !__STDC__ */
 
+/* DJGPP allows to detect at runtime if the used file system provides (LFN)
+   long file name support or not.  If LFN support is available then first look
+   for ".inputrc".  If a file with that file name does not exists try "_inputrc".
+   If only SFN is available then only try "_inputrc" as init file name.  */
+#if defined (__MSDOS__)
+#  if defined (__DJGPP__)
+#    define HAVE_LFN_SUPPORT(name)  ((pathconf((name), _PC_NAME_MAX) > 12) ? 1 : 0)
+#    undef  SYS_INPUTRC
+#    define SYS_INPUTRC             "/dev/env/DJDIR/etc/inputrc"
+#  else  /* !__DJGPP__ */
+#    define HAVE_LFN_SUPPORT(name)  (0)
+#  endif /* !__DJGPP__ */
+#endif /* !__MSDOS__ */
+
 /* Variables exported by this file. */
 Keymap rl_binding_keymap;
 
 static char *_rl_read_file PARAMS((char *, size_t *));
 static void _rl_init_file_error PARAMS((const char *));
@@ -446,11 +460,11 @@ rl_translate_keyseq (seq, array, len)
      char *array;
      int *len;
 {
   register int i, c, l, temp;
 
-  for (i = l = 0; c = seq[i]; i++)
+  for (i = l = 0; (c = seq[i]); i++)
     {
       if (c == '\\')
 	{
 	  c = seq[++i];
 
@@ -850,10 +864,13 @@ rl_read_init_file (filename)
     }
 
 #if defined (__MSDOS__)
   if (_rl_read_init_file (filename, 0) == 0)
     return 0;
+  filename = HAVE_LFN_SUPPORT(".inputrc") ? "~/.inputrc" : "~/_inputrc";
+  if (_rl_read_init_file (filename, 0) == 0)
+    return 0;
   filename = "~/_inputrc";
 #endif
   return (_rl_read_init_file (filename, 0));
 }
 
@@ -1192,11 +1209,11 @@ rl_parse_and_bind (string)
      backslash to quote characters in the key expression. */
   if (*string == '"')
     {
       int passc = 0;
 
-      for (i = 1; c = string[i]; i++)
+      for (i = 1; (c = string[i]); i++)
 	{
 	  if (passc)
 	    {
 	      passc = 0;
 	      continue;
@@ -1283,11 +1300,11 @@ rl_parse_and_bind (string)
   if (*funname == '\'' || *funname == '"')
     {
       int delimiter, passc;
 
       delimiter = string[i++];
-      for (passc = 0; c = string[i]; i++)
+      for (passc = 0; (c = string[i]); i++)
 	{
 	  if (passc)
 	    {
 	      passc = 0;
 	      continue;
@@ -2112,11 +2129,11 @@ rl_function_dumper (print_readably)
 
   names = rl_funmap_names ();
 
   fprintf (rl_outstream, "\n");
 
-  for (i = 0; name = names[i]; i++)
+  for (i = 0; (name = names[i]); i++)
     {
       rl_command_func_t *function;
       char **invokers;
 
       function = rl_named_function (name);
diff -aprNU5 gdb-7.12.1.orig/readline/complete.c gdb-7.12.1/readline/complete.c
--- gdb-7.12.1.orig/readline/complete.c	2017-01-21 13:48:42 +0000
+++ gdb-7.12.1/readline/complete.c	2019-02-24 16:06:12 +0000
@@ -99,10 +99,16 @@ rl_compdisp_func_t *rl_completion_displa
 #    define X_OK 1
 #  endif
 static int stat_char PARAMS((char *));
 #endif
 
+#if defined (__MSDOS__)
+#  define IS_SLASH(c)  ((c) == '/' || (c) == '\\')
+#else  /* !__MSDOS__ */
+#  define IS_SLASH(c)  ((c) == '/')
+#endif /* !__MSDOS__ */
+
 static int path_isdir PARAMS((const char *));
 
 static char *rl_quote_filename PARAMS((char *, int, char *));
 
 static void set_completion_defaults PARAMS((int));
@@ -648,13 +654,13 @@ printable_part (pathname)
      following that slash.  If there's no previous slash, just return the
      pathname we were passed. */
   else if (temp[1] == '\0')
     {
       for (x = temp - 1; x > pathname; x--)
-        if (*x == '/')
+        if (IS_SLASH(*x))
           break;
-      return ((*x == '/') ? x + 1 : pathname);
+      return (IS_SLASH(*x) ? x + 1 : pathname);
     }
   else
     return ++temp;
 }
 
@@ -997,17 +1003,23 @@ _rl_find_completion_word (fp, dp)
   if (rl_point == end && quote_char == '\0')
     {
       /* We didn't find an unclosed quoted substring upon which to do
          completion, so use the word break characters to find the
          substring on which to complete. */
-      while (rl_point = MB_PREVCHAR (rl_line_buffer, rl_point, MB_FIND_ANY))
+      while ((rl_point = MB_PREVCHAR (rl_line_buffer, rl_point, MB_FIND_ANY)))
 	{
 	  scan = rl_line_buffer[rl_point];
 
 	  if (strchr (brkchars, scan) == 0)
 	    continue;
 
+#if defined (__MSDOS__)
+          /* Ignore colons.  */
+          if (scan == ':' && (rl_completion_entry_function == NULL
+	      || (rl_completion_entry_function == rl_filename_completion_function)))
+	    continue;
+#endif
 	  /* Call the application-specific function to tell us whether
 	     this word break character is quoted and should be skipped. */
 	  if (rl_char_is_quoted_p && found_quote &&
 	      (*rl_char_is_quoted_p) (rl_line_buffer, rl_point))
 	    continue;
@@ -1610,13 +1622,25 @@ make_quoted_replacement (match, mtype, q
   if (should_quote)
     {
       /* If there is a single match, see if we need to quote it.
          This also checks whether the common prefix of several
 	 matches needs to be quoted. */
+#if !defined (__MSDOS__)
       should_quote = rl_filename_quote_characters
 			? (_rl_strpbrk (match, rl_filename_quote_characters) != 0)
 			: 0;
+#else  /* __MSDOS__ */
+      /* To get here, the match must be a filename.
+         Do not allow ':' to be quoted in DOS-style filenames,
+         to avoid confusing people.  */
+      char *token = NULL;
+      should_quote = rl_filename_quote_characters
+                      ? ((token = _rl_strpbrk (match, rl_filename_quote_characters)) != 0)
+                      : 0;
+      if (token && *token == ':')
+        should_quote = 0;
+#endif /* __MSDOS__ */
 
       do_replace = should_quote ? mtype : NO_MATCH;
       /* Quote the replacement, since we found an embedded
 	 word break character in a potential match. */
       if (do_replace != NO_MATCH && rl_filename_quoting_function)
@@ -2005,11 +2029,11 @@ rl_completion_matches (text, entry_funct
   match_list_size = 10;
   match_list = (char **)xmalloc ((match_list_size + 1) * sizeof (char *));
   match_list[1] = (char *)NULL;
 
   _rl_interrupt_immediately++;
-  while (string = (*entry_function) (text, matches))
+  while ((string = (*entry_function) (text, matches)))
     {
       if (matches + 1 == match_list_size)
 	match_list = (char **)xrealloc
 	  (match_list, ((match_list_size += 10) + 1) * sizeof (char *));
 
@@ -2058,11 +2082,11 @@ rl_username_completion_function (text, s
       namelen = strlen (username);
       setpwent ();
     }
 
 #if defined (HAVE_GETPWENT)
-  while (entry = getpwent ())
+  while ((entry = getpwent ()))
     {
       /* Null usernames should result in all users as possible completions. */
       if (namelen == 0 || (STREQN (username, entry->pw_name, namelen)))
 	break;
     }
@@ -2184,11 +2208,11 @@ rl_filename_completion_function (text, s
 	text = ".";
       dirname = savestring (text);
 
       temp = strrchr (dirname, '/');
 
-#if defined (__MSDOS__)
+#if defined (__MSDOS__) && !defined (__DJGPP__)
       /* special hack for //X/... */
       if (dirname[0] == '/' && dirname[1] == '/' && ISALPHA ((unsigned char)dirname[2]) && dirname[3] == '/')
         temp = strrchr (dirname + 3, '/');
 #endif
 
diff -aprNU5 gdb-7.12.1.orig/readline/display.c gdb-7.12.1/readline/display.c
--- gdb-7.12.1.orig/readline/display.c	2017-01-21 13:48:42 +0000
+++ gdb-7.12.1/readline/display.c	2019-02-24 16:06:12 +0000
@@ -2006,18 +2006,22 @@ _rl_move_cursor_relative (new, data)
 	 in the buffer and we have to go back to the beginning of the screen
 	 line.  In this case, we can use the terminal sequence to move forward
 	 if it's available. */
       if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
 	{
+#if !defined (__MSDOS__)
 	  if (_rl_term_forward_char)
 	    {
 	      for (i = cpos; i < dpos; i++)
 	        tputs (_rl_term_forward_char, 1, _rl_output_character_function);
 	    }
 	  else
+#endif  /* !__MSDOS__ */
 	    {
+#if !defined (__MSDOS__)
 	      tputs (_rl_term_cr, 1, _rl_output_character_function);
+#endif  /* !__MSDOS__ */
 	      for (i = 0; i < new; i++)
 		putc (data[i], rl_outstream);
 	    }
 	}
       else
@@ -2355,19 +2359,19 @@ space_to_eol (count)
 }
 
 void
 _rl_clear_screen ()
 {
-#if defined (__GO32__)
+#if defined (__DJGPP__)
   ScreenClear ();	/* FIXME: only works in text modes */
   ScreenSetCursor (0, 0);  /* term_clrpag is "cl" which homes the cursor */
-#else
+#else  /* !__DJGPP__ */
   if (_rl_term_clrpag)
     tputs (_rl_term_clrpag, 1, _rl_output_character_function);
   else
     rl_crlf ();
-#endif
+#endif  /* !__DJGPP__ */
 }
 
 /* Insert COUNT characters from STRING to the output stream at column COL. */
 static void
 insert_some_chars (string, count, col)
diff -aprNU5 gdb-7.12.1.orig/readline/doc/hstech.texi gdb-7.12.1/readline/doc/hstech.texi
--- gdb-7.12.1.orig/readline/doc/hstech.texi	2016-08-01 15:50:20 +0000
+++ gdb-7.12.1/readline/doc/hstech.texi	2019-02-24 16:06:12 +0000
@@ -317,10 +317,16 @@ index of the history element where @var{
 @subsection Managing the History File
 
 The History library can read the history from and write it to a file.
 This section documents the functions for managing a history file.
 
+For the @acronym{DJGPP} port of history library the default will be
+@file{~/.history} if the used operating system offers long file name
+support.  If this is not the case @file{~/_history} will be the default.
+If long file name support is available and @file{~/.history} could not
+be found then @file{~/_history} would be tried instead.
+
 @deftypefun int read_history (const char *filename)
 Add the contents of @var{filename} to the history list, a line at a time.
 If @var{filename} is @code{NULL}, then read from @file{~/.history}.
 Returns 0 if successful, or @code{errno} if not.
 @end deftypefun
diff -aprNU5 gdb-7.12.1.orig/readline/doc/rluser.texi gdb-7.12.1/readline/doc/rluser.texi
--- gdb-7.12.1.orig/readline/doc/rluser.texi	2016-08-01 15:50:20 +0000
+++ gdb-7.12.1/readline/doc/rluser.texi	2019-02-24 16:06:12 +0000
@@ -347,10 +347,17 @@ file is taken from the value of the envi
 @end ifclear
 that variable is unset, the default is @file{~/.inputrc}.  If that
 file does not exist or cannot be read, the ultimate default is
 @file{/etc/inputrc}.
 
+For the @acronym{DJGPP} port of the Readline library the default will be
+@file{~/.inputrc} if the used operating system offers long file name
+support.  If this is not the case @file{~/_inputrc} will be the default.
+If long file name support is available and @file{~/.inputrc} could not
+be found then @file{~/_inputrc} would be tried instead.  The ultimate
+default is @file{/dev/env/DJDIR/etc/inputrc}.
+
 When a program which uses the Readline library starts up, the
 init file is read, and the key bindings are set.
 
 In addition, the @code{C-x C-r} command re-reads this init file, thus
 incorporating any changes that you might have made to it.
diff -aprNU5 gdb-7.12.1.orig/readline/examples/fileman.c gdb-7.12.1/readline/examples/fileman.c
--- gdb-7.12.1.orig/readline/examples/fileman.c	2016-08-01 15:50:20 +0000
+++ gdb-7.12.1/readline/examples/fileman.c	2019-02-24 16:06:12 +0000
@@ -117,44 +117,10 @@ dupstr (s)
   r = xmalloc (strlen (s) + 1);
   strcpy (r, s);
   return (r);
 }
 
-main (argc, argv)
-     int argc;
-     char **argv;
-{
-  char *line, *s;
-
-  progname = argv[0];
-
-  initialize_readline ();	/* Bind our completer. */
-
-  /* Loop reading and executing lines until the user quits. */
-  for ( ; done == 0; )
-    {
-      line = readline ("FileMan: ");
-
-      if (!line)
-        break;
-
-      /* Remove leading and trailing whitespace from the line.
-         Then, if there is anything left, add it to the history list
-         and execute it. */
-      s = stripwhite (line);
-
-      if (*s)
-        {
-          add_history (s);
-          execute_line (s);
-        }
-
-      free (line);
-    }
-  exit (0);
-}
-
 /* Execute a command line. */
 int
 execute_line (line)
      char *line;
 {
@@ -227,10 +193,35 @@ stripwhite (string)
   *++t = '\0';
 
   return s;
 }
 
+/* Function which tells you that you can't do this. */
+void
+too_dangerous (caller)
+     char *caller;
+{
+  fprintf (stderr,
+           "%s: Too dangerous for me to distribute.  Write it yourself.\n",
+           caller);
+}
+
+/* Return non-zero if ARG is a valid argument for CALLER, else print
+   an error message and return zero. */
+int
+valid_argument (caller, arg)
+     char *caller, *arg;
+{
+  if (!arg || !*arg)
+    {
+      fprintf (stderr, "%s: Argument required.\n", caller);
+      return (0);
+    }
+
+  return (1);
+}
+
 /* **************************************************************** */
 /*                                                                  */
 /*                  Interface to Readline Completion                */
 /*                                                                  */
 /* **************************************************************** */
@@ -239,10 +230,11 @@ char *command_generator PARAMS((const ch
 char **fileman_completion PARAMS((const char *, int, int));
 
 /* Tell the GNU Readline library how to complete.  We want to try to complete
    on command names if this is the first word in the line, or on filenames
    if not. */
+void
 initialize_readline ()
 {
   /* Allow conditional parsing of the ~/.inputrc file. */
   rl_readline_name = "FileMan";
 
@@ -292,11 +284,11 @@ command_generator (text, state)
       list_index = 0;
       len = strlen (text);
     }
 
   /* Return the next name which partially matches from the command list. */
-  while (name = commands[list_index].name)
+  while ((name = commands[list_index].name))
     {
       list_index++;
 
       if (strncmp (name, text, len) == 0)
         return (dupstr(name));
@@ -315,20 +307,22 @@ command_generator (text, state)
 /* String to pass to system ().  This is for the LIST, VIEW and RENAME
    commands. */
 static char syscom[1024];
 
 /* List the file(s) named in arg. */
+int
 com_list (arg)
      char *arg;
 {
   if (!arg)
     arg = "";
 
   sprintf (syscom, "ls -FClg %s", arg);
   return (system (syscom));
 }
 
+int
 com_view (arg)
      char *arg;
 {
   if (!valid_argument ("view", arg))
     return 1;
@@ -340,17 +334,19 @@ com_view (arg)
   sprintf (syscom, "more %s", arg);
 #endif
   return (system (syscom));
 }
 
+int
 com_rename (arg)
      char *arg;
 {
   too_dangerous ("rename");
   return (1);
 }
 
+int
 com_stat (arg)
      char *arg;
 {
   struct stat finfo;
 
@@ -375,19 +371,21 @@ com_stat (arg)
   printf ("      Last access at: %s", ctime (&finfo.st_atime));
   printf ("    Last modified at: %s", ctime (&finfo.st_mtime));
   return (0);
 }
 
+int
 com_delete (arg)
      char *arg;
 {
   too_dangerous ("delete");
   return (1);
 }
 
 /* Print out help for ARG, or for all of the commands if ARG is
    not present. */
+int
 com_help (arg)
      char *arg;
 {
   register int i;
   int printed = 0;
@@ -423,10 +421,11 @@ com_help (arg)
     }
   return (0);
 }
 
 /* Change to the directory ARG. */
+int
 com_cd (arg)
      char *arg;
 {
   if (chdir (arg) == -1)
     {
@@ -437,10 +436,11 @@ com_cd (arg)
   com_pwd ("");
   return (0);
 }
 
 /* Print out the current working directory. */
+int
 com_pwd (ignore)
      char *ignore;
 {
   char dir[1024], *s;
 
@@ -454,35 +454,47 @@ com_pwd (ignore)
   printf ("Current directory is %s\n", dir);
   return 0;
 }
 
 /* The user wishes to quit using this program.  Just set DONE non-zero. */
+int
 com_quit (arg)
      char *arg;
 {
   done = 1;
   return (0);
 }
 
-/* Function which tells you that you can't do this. */
-too_dangerous (caller)
-     char *caller;
-{
-  fprintf (stderr,
-           "%s: Too dangerous for me to distribute.  Write it yourself.\n",
-           caller);
-}
-
-/* Return non-zero if ARG is a valid argument for CALLER, else print
-   an error message and return zero. */
 int
-valid_argument (caller, arg)
-     char *caller, *arg;
+main (argc, argv)
+     int argc;
+     char **argv;
 {
-  if (!arg || !*arg)
+  char *line, *s;
+
+  progname = argv[0];
+
+  initialize_readline ();	/* Bind our completer. */
+
+  /* Loop reading and executing lines until the user quits. */
+  for ( ; done == 0; )
     {
-      fprintf (stderr, "%s: Argument required.\n", caller);
-      return (0);
-    }
+      line = readline ("FileMan: ");
 
-  return (1);
+      if (!line)
+        break;
+
+      /* Remove leading and trailing whitespace from the line.
+         Then, if there is anything left, add it to the history list
+         and execute it. */
+      s = stripwhite (line);
+
+      if (*s)
+        {
+          add_history (s);
+          execute_line (s);
+        }
+
+      free (line);
+    }
+  exit (0);
 }
diff -aprNU5 gdb-7.12.1.orig/readline/examples/histexamp.c gdb-7.12.1/readline/examples/histexamp.c
--- gdb-7.12.1.orig/readline/examples/histexamp.c	2016-08-01 15:50:20 +0000
+++ gdb-7.12.1/readline/examples/histexamp.c	2019-02-24 16:06:12 +0000
@@ -19,18 +19,25 @@
    along with Readline.  If not, see <http://www.gnu.org/licenses/>.
 */
 
 #include <stdio.h>
 
+#ifdef HAVE_STDLIB_H
+#  include <stdlib.h>
+#else 
+extern void free ();
+#endif
+
 #ifdef READLINE_LIBRARY
 #  include "history.h"
 #else
 #  include <readline/history.h>
 #endif
 
 #include <string.h>
 
+int
 main (argc, argv)
      int argc;
      char **argv;
 {
   char line[1024], *t;
@@ -120,6 +127,7 @@ main (argc, argv)
 	    {
 	      fprintf (stderr, "non-numeric arg given to `delete'\n");
 	    }
 	}
     }
+  return 0;
 }
diff -aprNU5 gdb-7.12.1.orig/readline/examples/rl.c gdb-7.12.1/readline/examples/rl.c
--- gdb-7.12.1.orig/readline/examples/rl.c	2016-08-01 15:50:20 +0000
+++ gdb-7.12.1/readline/examples/rl.c	2019-02-24 16:06:12 +0000
@@ -35,20 +35,50 @@
 #  include <stdlib.h>
 #else 
 extern void exit();
 #endif
 
+#if defined (HAVE_UNISTD_H)
+#  include <unistd.h>
+#endif /* HAVE_UNISTD_H */
+
 #if defined (READLINE_LIBRARY)
 #  include "posixstat.h"
 #  include "readline.h"
 #  include "history.h"
 #else
 #  include <sys/stat.h>
 #  include <readline/readline.h>
 #  include <readline/history.h>
 #endif
 
+#if defined (__DJGPP__)
+# undef  IS_DIR_SEPARATOR
+# define IS_DIR_SEPARATOR(c)  ((c) == '/' || (c) == '\\' || (c) == ':')
+# include <libc/unconst.h>
+# define STRIP_FULL_PATH_AND_EXTENSION(file_name)   \
+  (__extension__                                    \
+    ({                                              \
+       char *_dst, *_src;                           \
+       _dst = _src = unconst((file_name), char *);  \
+       while (*_src++)                              \
+         ;                                          \
+       while ((_src - _dst) && (*--_src != '.'))    \
+         ;                                          \
+       for (*_src = '\0'; (_src - _dst); _src--)    \
+         if (IS_DIR_SEPARATOR(*_src))               \
+           break;                                   \
+       if (_src - _dst)                             \
+         while ((*_dst++ = *++_src))                \
+           ;                                        \
+       (file_name);                                 \
+    })                                              \
+  )
+#else  /* !__DJGPP__ */
+# define STRIP_FULL_PATH_AND_EXTENSION(file_name)  (file_name)
+#endif /* !__DJGPP__ */
+
 extern int optind;
 extern char *optarg;
 
 #if !defined (strchr) && !defined (__STDC__)
 extern char *strrchr();
@@ -84,11 +114,11 @@ main (argc, argv)
   char *temp, *prompt;
   struct stat sb;
   int opt, fd, nch;
   FILE *ifp;
 
-  progname = strrchr(argv[0], '/');
+  progname = STRIP_FULL_PATH_AND_EXTENSION(argv[0]);
   if (progname == 0)
     progname = argv[0];
   else
     progname++;
 
diff -aprNU5 gdb-7.12.1.orig/readline/examples/rlcat.c gdb-7.12.1/readline/examples/rlcat.c
--- gdb-7.12.1.orig/readline/examples/rlcat.c	2016-08-01 15:50:20 +0000
+++ gdb-7.12.1/readline/examples/rlcat.c	2019-02-24 16:06:12 +0000
@@ -55,10 +55,36 @@ extern int errno;
 #else
 #  include <readline/readline.h>
 #  include <readline/history.h>
 #endif
 
+#if defined (__DJGPP__)
+# undef  IS_DIR_SEPARATOR
+# define IS_DIR_SEPARATOR(c)  ((c) == '/' || (c) == '\\' || (c) == ':')
+# include <libc/unconst.h>
+# define STRIP_FULL_PATH_AND_EXTENSION(file_name)   \
+  (__extension__                                    \
+    ({                                              \
+       char *_dst, *_src;                           \
+       _dst = _src = unconst((file_name), char *);  \
+       while (*_src++)                              \
+         ;                                          \
+       while ((_src - _dst) && (*--_src != '.'))    \
+         ;                                          \
+       for (*_src = '\0'; (_src - _dst); _src--)    \
+         if (IS_DIR_SEPARATOR(*_src))               \
+           break;                                   \
+       if (_src - _dst)                             \
+         while ((*_dst++ = *++_src))                \
+           ;                                        \
+       (file_name);                                 \
+    })                                              \
+  )
+#else  /* !__DJGPP__ */
+# define STRIP_FULL_PATH_AND_EXTENSION(file_name)  (file_name)
+#endif /* !__DJGPP__ */
+
 extern int optind;
 extern char *optarg;
 
 static int stdcat();
 
@@ -77,11 +103,11 @@ main (argc, argv)
      char **argv;
 {
   char *temp;
   int opt, Vflag, Nflag;
 
-  progname = strrchr(argv[0], '/');
+  progname = STRIP_FULL_PATH_AND_EXTENSION(argv[0]);
   if (progname == 0)
     progname = argv[0];
   else
     progname++;
 
@@ -113,11 +139,11 @@ main (argc, argv)
 
   if (isatty(0) == 0 || argc || Nflag)
     return stdcat(argc, argv);
 
   rl_variable_bind ("editing-mode", Vflag ? "vi" : "emacs");
-  while (temp = readline (""))
+  while ((temp = readline ("")))
     {
       if (*temp)
         add_history (temp);
       printf ("%s\n", temp);
     }
diff -aprNU5 gdb-7.12.1.orig/readline/examples/rlevent.c gdb-7.12.1/readline/examples/rlevent.c
--- gdb-7.12.1.orig/readline/examples/rlevent.c	2016-08-01 15:50:20 +0000
+++ gdb-7.12.1/readline/examples/rlevent.c	2019-02-24 16:06:12 +0000
@@ -35,20 +35,50 @@
 #  include <stdlib.h>
 #else 
 extern void exit();
 #endif
 
+#if defined (HAVE_UNISTD_H)
+#  include <unistd.h>
+#endif /* HAVE_UNISTD_H */
+
 #if defined (READLINE_LIBRARY)
 #  include "posixstat.h"
 #  include "readline.h"
 #  include "history.h"
 #else
 #  include <sys/stat.h>
 #  include <readline/readline.h>
 #  include <readline/history.h>
 #endif
 
+#if defined (__DJGPP__)
+# undef  IS_DIR_SEPARATOR
+# define IS_DIR_SEPARATOR(c)  ((c) == '/' || (c) == '\\' || (c) == ':')
+# include <libc/unconst.h>
+# define STRIP_FULL_PATH_AND_EXTENSION(file_name)   \
+  (__extension__                                    \
+    ({                                              \
+       char *_dst, *_src;                           \
+       _dst = _src = unconst((file_name), char *);  \
+       while (*_src++)                              \
+         ;                                          \
+       while ((_src - _dst) && (*--_src != '.'))    \
+         ;                                          \
+       for (*_src = '\0'; (_src - _dst); _src--)    \
+         if (IS_DIR_SEPARATOR(*_src))               \
+           break;                                   \
+       if (_src - _dst)                             \
+         while ((*_dst++ = *++_src))                \
+           ;                                        \
+       (file_name);                                 \
+    })                                              \
+  )
+#else  /* !__DJGPP__ */
+# define STRIP_FULL_PATH_AND_EXTENSION(file_name)  (file_name)
+#endif /* !__DJGPP__ */
+
 extern int optind;
 extern char *optarg;
 
 #if !defined (strchr) && !defined (__STDC__)
 extern char *strrchr();
@@ -92,11 +122,11 @@ main (argc, argv)
   char *temp, *prompt;
   struct stat sb;
   int opt, fd, nch;
   FILE *ifp;
 
-  progname = strrchr(argv[0], '/');
+  progname = STRIP_FULL_PATH_AND_EXTENSION(argv[0]);
   if (progname == 0)
     progname = argv[0];
   else
     progname++;
 
diff -aprNU5 gdb-7.12.1.orig/readline/examples/rltest.c gdb-7.12.1/readline/examples/rltest.c
--- gdb-7.12.1.orig/readline/examples/rltest.c	2016-08-01 15:50:20 +0000
+++ gdb-7.12.1/readline/examples/rltest.c	2019-02-24 16:06:12 +0000
@@ -44,10 +44,11 @@ extern void exit();
 #  include <readline/history.h>
 #endif
 
 extern HIST_ENTRY **history_list ();
 
+int
 main ()
 {
   char *temp, *prompt;
   int done;
 
diff -aprNU5 gdb-7.12.1.orig/readline/examples/rlversion.c gdb-7.12.1/readline/examples/rlversion.c
--- gdb-7.12.1.orig/readline/examples/rlversion.c	2016-08-01 15:50:20 +0000
+++ gdb-7.12.1/readline/examples/rlversion.c	2019-02-24 16:06:12 +0000
@@ -39,10 +39,11 @@ extern void exit();
 #  include "readline.h"
 #else
 #  include <readline/readline.h>
 #endif
 
+int
 main()
 {
 	printf ("%s\n", rl_library_version ? rl_library_version : "unknown");
 	exit (0);
 }
diff -aprNU5 gdb-7.12.1.orig/readline/funmap.c gdb-7.12.1/readline/funmap.c
--- gdb-7.12.1.orig/readline/funmap.c	2017-01-21 13:48:42 +0000
+++ gdb-7.12.1/readline/funmap.c	2019-02-24 16:06:12 +0000
@@ -111,11 +111,11 @@ static const FUNMAP default_funmap[] = {
   { "non-incremental-reverse-search-history", rl_noninc_reverse_search },
   { "non-incremental-forward-search-history-again", rl_noninc_forward_search_again },
   { "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__
+#if defined (__CYGWIN__) || defined (__DJGPP__)
   { "paste-from-clipboard", rl_paste_from_clipboard },
 #endif
   { "possible-completions", rl_possible_completions },
   { "previous-history", rl_get_previous_history },
   { "quoted-insert", rl_quoted_insert },
diff -aprNU5 gdb-7.12.1.orig/readline/histexpand.c gdb-7.12.1/readline/histexpand.c
--- gdb-7.12.1.orig/readline/histexpand.c	2016-08-01 15:50:20 +0000
+++ gdb-7.12.1/readline/histexpand.c	2019-02-24 16:06:12 +0000
@@ -202,11 +202,11 @@ get_history_event (string, caller_index,
       substring_okay++;
       i++;
     }
 
   /* Only a closing `?' or a newline delimit a substring search string. */
-  for (local_index = i; c = string[i]; i++)
+  for (local_index = i; (c = string[i]); i++)
     {
 #if defined (HANDLE_MULTIBYTE)
       if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
 	{
 	  int v;
diff -aprNU5 gdb-7.12.1.orig/readline/histfile.c gdb-7.12.1/readline/histfile.c
--- gdb-7.12.1.orig/readline/histfile.c	2017-01-21 13:48:42 +0000
+++ gdb-7.12.1/readline/histfile.c	2019-02-24 16:06:12 +0000
@@ -74,21 +74,35 @@
 #  endif
 
 #endif /* HISTORY_USE_MMAP */
 
 /* If we're compiling for __EMX__ (OS/2) or __CYGWIN__ (cygwin32 environment
-   on win 95/98/nt), we want to open files with O_BINARY mode so that there
-   is no \n -> \r\n conversion performed.  On other systems, we don't want to
-   mess around with O_BINARY at all, so we ensure that it's defined to 0. */
-#if defined (__EMX__) || defined (__CYGWIN__)
+   on win 95/98/nt), or DJGPP (DOS), we want to open files with O_BINARY mode
+   so that there is no \n -> \r\n conversion performed.  On other systems,
+   we don't want to mess around with O_BINARY at all, so we ensure that
+   it's defined to 0. */
+#if defined (__EMX__) || defined (__DJGPP__) || defined (__CYGWIN__)
 #  ifndef O_BINARY
 #    define O_BINARY 0
 #  endif
-#else /* !__EMX__ && !__CYGWIN__ */
+#else /* !__EMX__ && !__DJGPP__ && !__CYGWIN__ */
 #  undef O_BINARY
 #  define O_BINARY 0
-#endif /* !__EMX__ && !__CYGWIN__ */
+#endif /* !__EMX__ && !__DJGPP__ && !__CYGWIN__ */
+
+/* DJGPP allows to detect at runtime if the file system used provides (LFN)
+   long file name support or not.  If LFN support is available then look first
+   for ".history".  If a file with that file name does not exists try "_history".
+   If only SFN support is available then only try "_history" as history file name.  */
+#if defined (__MSDOS__)
+#  if defined (__DJGPP__)
+#    define HAVE_LFN_SUPPORT(name)   ((pathconf((name), _PC_NAME_MAX) > 12) ? 1 : 0)
+#    define FILE_EXISTS(name)        (access((name), F_OK) == 0)
+#  else  /* !__DJGPP__ */
+#    define HAVE_LFN_SUPPORT(name)   (0)
+#  endif /* !__DJGPP__ */
+#endif /* !__MSDOS__ */
 
 #include <errno.h>
 #if !defined (errno)
 extern int errno;
 #endif /* !errno */
@@ -138,11 +152,14 @@ history_filename (filename)
 
   return_val = (char *)xmalloc (2 + home_len + 8); /* strlen(".history") == 8 */
   strcpy (return_val, home);
   return_val[home_len] = '/';
 #if defined (__MSDOS__)
-  strcpy (return_val + home_len + 1, "_history");
+  if (HAVE_LFN_SUPPORT(".history"))
+    strcpy (return_val + home_len + 1, FILE_EXISTS(".history") ? ".history" : "_history");
+  else
+    strcpy (return_val + home_len + 1, "_history");
 #else
   strcpy (return_val + home_len + 1, ".history");
 #endif
 
   return (return_val);
diff -aprNU5 gdb-7.12.1.orig/readline/input.c gdb-7.12.1/readline/input.c
--- gdb-7.12.1.orig/readline/input.c	2017-01-21 13:48:42 +0000
+++ gdb-7.12.1/readline/input.c	2019-02-24 16:06:12 +0000
@@ -419,11 +419,11 @@ rl_read_key ()
       rl_clear_pending_input ();
     }
   else
     {
       /* If input is coming from a macro, then use that. */
-      if (c = _rl_next_macro_key ())
+      if ((c = _rl_next_macro_key ()))
 	return (c);
 
       /* If the user has an event function, then call it periodically. */
       if (rl_event_hook)
 	{
diff -aprNU5 gdb-7.12.1.orig/readline/kill.c gdb-7.12.1/readline/kill.c
--- gdb-7.12.1.orig/readline/kill.c	2017-01-21 13:48:42 +0000
+++ gdb-7.12.1/readline/kill.c	2019-02-24 16:06:12 +0000
@@ -690,5 +690,78 @@ rl_paste_from_clipboard (count, key)
       CloseClipboard ();
     }
   return (0);
 }
 #endif /* __CYGWIN__ */
+
+/* A special paste command to allow DJGPP users to paste
+   from the Windows clipboard. */
+#if defined (__DJGPP__)
+#include <dpmi.h>
+#include <sys/farptr.h>
+#include <go32.h>
+
+int
+rl_paste_from_clipboard (count, key)
+     int count, key;
+{
+  char *ptr;
+  int len, index;
+  __dpmi_regs r;
+  unsigned long offset;
+  char ch;
+ 
+  /* Open the Windows clipboard.  */
+  r.x.ax = 0x1701;
+  __dpmi_int(0x2f, &r);
+  if (r.x.ax == 0)
+    return 0;
+
+  /* Get the size of the text in the clipboard.  */
+  r.x.ax = 0x1704;
+  r.x.dx = 1; /* Select plain text.  */
+  __dpmi_int(0x2f, &r);
+  len = r.x.ax + 65536 * r.x.dx;
+  if (len == 0)
+    return 0;
+
+  /* Get a pointer to the text.  */
+  r.x.ax = 0x1705;
+  r.x.dx = 1;
+  __dpmi_int(0x2f, &r);
+
+  offset = r.x.bx + 16 * r.x.es;
+  if (offset == 0)
+    return 0;
+
+  _farsetsel(_dos_ds);
+  while ((ch = _farnspeekb(offset++)) != '\0')
+  {
+    if (ch == '\r')
+      break;
+  }
+  len = offset - (r.x.bx + 16 * r.x.es);
+  if (ch == '\r')
+    --len;
+
+  ptr = xmalloc(len + 1);
+  offset = r.x.bx + 16 * r.x.es;
+
+  index = 0;
+  _farsetsel(_dos_ds);
+  while (index < len)
+  {
+    ch = _farnspeekb(offset++);
+    ptr[index++] = ch;
+  }
+  ptr[len] = '\0';
+
+  /* Close the clipboard.  */
+  r.x.ax = 0x1708;
+  __dpmi_int(0x2f, &r);
+
+  rl_insert_text(ptr);
+  free(ptr);
+
+  return 0;
+}
+#endif /* __DJGPP__ */
diff -aprNU5 gdb-7.12.1.orig/readline/misc.c gdb-7.12.1/readline/misc.c
--- gdb-7.12.1.orig/readline/misc.c	2016-08-01 15:50:20 +0000
+++ gdb-7.12.1/readline/misc.c	2019-02-24 16:06:12 +0000
@@ -451,11 +451,11 @@ _rl_revert_all_lines ()
   hpos = where_history ();
 
   entry = (hpos == history_length) ? previous_history () : current_history ();
   while (entry)
     {
-      if (ul = (UNDO_LIST *)entry->data)
+      if ((ul = (UNDO_LIST *)entry->data))
 	{
 	  if (ul == saved_undo_list)
 	    saved_undo_list = 0;
 	  /* Set up rl_line_buffer and other variables from history entry */
 	  rl_replace_from_history (entry, 0);	/* entry->line is now current */
diff -aprNU5 gdb-7.12.1.orig/readline/readline.c gdb-7.12.1/readline/readline.c
--- gdb-7.12.1.orig/readline/readline.c	2016-08-01 15:50:20 +0000
+++ gdb-7.12.1/readline/readline.c	2019-02-24 16:06:12 +0000
@@ -62,10 +62,15 @@ extern int errno;
 #if defined (__EMX__)
 #  define INCL_DOSPROCESS
 #  include <os2.h>
 #endif /* __EMX__ */
 
+#if defined (__DJGPP__)
+#  include <sys/exceptn.h>
+extern int __libc_termios_enable_function_and_arrow_keys (void);
+#endif /* __DJGPP__ */
+
 /* Some standard library routines. */
 #include "readline.h"
 #include "history.h"
 
 #include "rlprivate.h"
@@ -88,11 +93,13 @@ static void readline_initialize_everythi
 
 static void bind_arrow_keys_internal PARAMS((Keymap));
 static void bind_arrow_keys PARAMS((void));
 
 static void readline_default_bindings PARAMS((void));
+#if !defined (__MSDOS__)
 static void reset_default_bindings PARAMS((void));
+#endif
 
 static int _rl_subseq_result PARAMS((int, Keymap, int, int));
 static int _rl_subseq_getchar PARAMS((int));
 
 /* **************************************************************** */
@@ -571,11 +578,11 @@ readline_internal_charloop ()
 
 #if defined (READLINE_CALLBACKS)
 static int
 readline_internal_charloop ()
 {
-  int eof = 1;
+  int eof = -1;
 
   while (rl_done == 0)
     eof = readline_internal_char ();
   return (eof);
 }
@@ -1064,10 +1071,13 @@ readline_initialize_everything ()
   if (rl_terminal_name == 0)
     rl_terminal_name = sh_get_env_value ("TERM");
   _rl_init_terminal_io (rl_terminal_name);
 
   /* Bind tty characters to readline functions. */
+#if defined (__DJGPP__)
+  __libc_termios_enable_function_and_arrow_keys ();
+#endif /* __DJGPP__ */
   readline_default_bindings ();
 
   /* Initialize the function names. */
   rl_initialize_funmap ();
 
@@ -1109,10 +1119,11 @@ readline_default_bindings ()
 {
   if (_rl_bind_stty_chars)
     rl_tty_set_default_bindings (_rl_keymap);
 }
 
+#if !defined (__MSDOS__)
 /* Reset the default bindings for the terminal special characters we're
    interested in back to rl_insert and read the new ones. */
 static void
 reset_default_bindings ()
 {
@@ -1120,10 +1131,11 @@ reset_default_bindings ()
     {
       rl_tty_unset_default_bindings (_rl_keymap);
       rl_tty_set_default_bindings (_rl_keymap);
     }
 }
+#endif
 
 /* Bind some common arrow key sequences in MAP. */
 static void
 bind_arrow_keys_internal (map)
      Keymap map;
diff -aprNU5 gdb-7.12.1.orig/readline/readline.h gdb-7.12.1/readline/readline.h
--- gdb-7.12.1.orig/readline/readline.h	2017-01-21 13:48:42 +0000
+++ gdb-7.12.1/readline/readline.h	2019-02-24 16:06:12 +0000
@@ -170,12 +170,12 @@ extern int rl_copy_forward_word PARAMS((
 extern int rl_copy_backward_word PARAMS((int, int));
 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 __CYGWIN__ or __DJGPP__ is defined. */
+#if defined (__CYGWIN__) || defined (__DJGPP__)
 extern int rl_paste_from_clipboard PARAMS((int, int));
 #endif
 
 /* Bindable commands for incremental searching. */
 extern int rl_reverse_search_history PARAMS((int, int));
diff -aprNU5 gdb-7.12.1.orig/readline/signals.c gdb-7.12.1/readline/signals.c
--- gdb-7.12.1.orig/readline/signals.c	2016-08-01 15:50:20 +0000
+++ gdb-7.12.1/readline/signals.c	2019-02-24 16:06:12 +0000
@@ -108,11 +108,13 @@ int _rl_echoctl = 0;
 int _rl_intr_char = 0;
 int _rl_quit_char = 0;
 int _rl_susp_char = 0;
 
 static int signals_set_flag;
+#ifdef SIGWINCH
 static int sigwinch_set_flag;
+#endif
 
 /* **************************************************************** */
 /*					        		    */
 /*			   Signal Handling                          */
 /*								    */
@@ -519,20 +521,26 @@ rl_free_line_state ()
 /*								    */
 /* **************************************************************** */
 
 #if defined (HAVE_POSIX_SIGNALS)
 static sigset_t sigint_set, sigint_oset;
+#  if defined (SIGWINCH)
 static sigset_t sigwinch_set, sigwinch_oset;
+#  endif /* SIGWINCH */
 #else /* !HAVE_POSIX_SIGNALS */
 #  if defined (HAVE_BSD_SIGNALS)
 static int sigint_oldmask;
+#    if defined (SIGWINCH)
 static int sigwinch_oldmask;
+#    endif /* SIGWINCH */
 #  endif /* HAVE_BSD_SIGNALS */
 #endif /* !HAVE_POSIX_SIGNALS */
 
 static int sigint_blocked;
+#if defined (SIGWINCH)
 static int sigwinch_blocked;
+#endif /* SIGWINCH */
 
 /* Cause SIGINT to not be delivered until the corresponding call to
    release_sigint(). */
 void
 _rl_block_sigint ()
diff -aprNU5 gdb-7.12.1.orig/readline/tcap.h gdb-7.12.1/readline/tcap.h
--- gdb-7.12.1.orig/readline/tcap.h	2017-01-21 13:48:42 +0000
+++ gdb-7.12.1/readline/tcap.h	2019-02-24 16:06:12 +0000
@@ -30,10 +30,11 @@
 #  if defined (__linux__) && !defined (SPEED_T_IN_SYS_TYPES)
 #    include "rltty.h"
 #  endif
 #  include <termcap.h>
 #else
+#  if !defined (__MSDOS__) /* On MS-DOS, no termcap is needed/available. */
 
 /* On Solaris2, sys/types.h #includes sys/reg.h, which #defines PC.
    Unfortunately, PC is a global variable used by the termcap library. */
 #ifdef PC
 #  undef PC
@@ -50,9 +51,10 @@ extern int tgetnum ();
 extern char *tgetstr ();
 
 extern int tputs ();
 
 extern char *tgoto ();
+#  endif /* !__MSDOS__ */
 
 #endif /* HAVE_TERMCAP_H */
 
 #endif /* !_RLTCAP_H_ */
diff -aprNU5 gdb-7.12.1.orig/readline/terminal.c gdb-7.12.1/readline/terminal.c
--- gdb-7.12.1.orig/readline/terminal.c	2016-08-01 15:50:20 +0000
+++ gdb-7.12.1/readline/terminal.c	2019-02-24 16:06:12 +0000
@@ -93,17 +93,10 @@ int rl_prefer_env_winsize = 0;
 /*								    */
 /*			Terminal and Termcap			    */
 /*								    */
 /* **************************************************************** */
 
-#ifndef __MSDOS__
-static char *term_buffer = (char *)NULL;
-static char *term_string_buffer = (char *)NULL;
-#endif /* !__MSDOS__ */
-
-static int tcap_initialized;
-
 #if !defined (__linux__) && !defined (NCURSES_VERSION)
 #  if defined (__EMX__) || defined (NEED_EXTERN_PC)
 extern 
 #  endif /* __EMX__ || NEED_EXTERN_PC */
 char PC, *BC, *UP;
@@ -134,19 +127,35 @@ char *_rl_term_DC;
 char *_rl_term_forward_char;
 
 /* How to go up a line. */
 char *_rl_term_up;
 
-/* A visible bell; char if the terminal can be made to flash the screen. */
-static char *_rl_visible_bell;
-
 /* Non-zero means the terminal can auto-wrap lines. */
 int _rl_term_autowrap = -1;
 
+/* Variables that hold the screen dimensions, used by the display code. */
+int _rl_screenwidth, _rl_screenheight, _rl_screenchars;
+
+/* Non-zero means the user wants to enable the keypad. */
+int _rl_enable_keypad;
+
+/* Non-zero means the user wants to enable a meta key. */
+int _rl_enable_meta = 1;
+
+#if !defined (__MSDOS__)
+
+static char *term_buffer = (char *)NULL;
+static char *term_string_buffer = (char *)NULL;
+
+static int tcap_initialized;
+
 /* Non-zero means that this terminal has a meta key. */
 static int term_has_meta;
 
+/* A visible bell; char if the terminal can be made to flash the screen. */
+static char *_rl_visible_bell;
+
 /* The sequences to write to turn on and off the meta key, if this
    terminal has one. */
 static char *_rl_term_mm;
 static char *_rl_term_mo;
 
@@ -175,19 +184,10 @@ static char *_rl_term_kI;
 static char *_rl_term_vs;	/* very visible */
 static char *_rl_term_ve;	/* normal */
 
 static void bind_termcap_arrow_keys PARAMS((Keymap));
 
-/* Variables that hold the screen dimensions, used by the display code. */
-int _rl_screenwidth, _rl_screenheight, _rl_screenchars;
-
-/* Non-zero means the user wants to enable the keypad. */
-int _rl_enable_keypad;
-
-/* Non-zero means the user wants to enable a meta key. */
-int _rl_enable_meta = 1;
-
 #if defined (__EMX__)
 static void
 _emx_get_screensize (swp, shp)
      int *swp, *shp;
 {
@@ -315,47 +315,10 @@ _rl_get_screen_size (tty, ignore_env)
 
   _rl_screenchars = _rl_screenwidth * _rl_screenheight;
 }
 
 void
-_rl_set_screen_size (rows, cols)
-     int rows, cols;
-{
-  if (_rl_term_autowrap == -1)
-    _rl_init_terminal_io (rl_terminal_name);
-
-  if (rows > 0)
-    _rl_screenheight = rows;
-  if (cols > 0)
-    {
-      _rl_screenwidth = cols;
-      if (_rl_term_autowrap == 0)
-	_rl_screenwidth--;
-    }
-
-  if (rows > 0 || cols > 0)
-    _rl_screenchars = _rl_screenwidth * _rl_screenheight;
-}
-
-void
-rl_set_screen_size (rows, cols)
-     int rows, cols;
-{
-  _rl_set_screen_size (rows, cols);
-}
-
-void
-rl_get_screen_size (rows, cols)
-     int *rows, *cols;
-{
-  if (rows)
-    *rows = _rl_screenheight;
-  if (cols)
-    *cols = _rl_screenwidth;
-}
-
-void
 rl_reset_screen_size ()
 {
   _rl_get_screen_size (fileno (rl_instream), 0);
 }
      
@@ -419,22 +382,96 @@ static const struct _tc_string tc_string
 static void
 get_term_capabilities (bp)
      char **bp;
 {
 #if !defined (__DJGPP__)	/* XXX - doesn't DJGPP have a termcap library? */
-  register int i;
+  register size_t i;
 
   for (i = 0; i < NUM_TC_STRINGS; i++)
     *(tc_strings[i].tc_value) = tgetstr ((char *)tc_strings[i].tc_var, bp);
 #endif
   tcap_initialized = 1;
 }
 
+/* Bind the arrow key sequences from the termcap description in MAP. */
+static void
+bind_termcap_arrow_keys (map)
+     Keymap map;
+{
+  Keymap xkeymap;
+
+  xkeymap = _rl_keymap;
+  _rl_keymap = map;
+
+  rl_bind_keyseq_if_unbound (_rl_term_ku, rl_get_previous_history);
+  rl_bind_keyseq_if_unbound (_rl_term_kd, rl_get_next_history);
+  rl_bind_keyseq_if_unbound (_rl_term_kr, rl_forward_char);
+  rl_bind_keyseq_if_unbound (_rl_term_kl, rl_backward_char);
+
+  rl_bind_keyseq_if_unbound (_rl_term_kh, rl_beg_of_line);	/* Home */
+  rl_bind_keyseq_if_unbound (_rl_term_at7, rl_end_of_line);	/* End */
+
+  rl_bind_keyseq_if_unbound (_rl_term_kD, rl_delete);
+
+  _rl_keymap = xkeymap;
+}
+
+#endif	/* !__MSDOS__ */
+
+void
+_rl_set_screen_size (rows, cols)
+     int rows, cols;
+{
+  if (_rl_term_autowrap == -1)
+    _rl_init_terminal_io (rl_terminal_name);
+
+  if (rows > 0)
+    _rl_screenheight = rows;
+  if (cols > 0)
+    {
+      _rl_screenwidth = cols;
+      if (_rl_term_autowrap == 0)
+	_rl_screenwidth--;
+    }
+
+  if (rows > 0 || cols > 0)
+    _rl_screenchars = _rl_screenwidth * _rl_screenheight;
+}
+
+void
+rl_set_screen_size (rows, cols)
+     int rows, cols;
+{
+  _rl_set_screen_size (rows, cols);
+}
+
+void
+rl_get_screen_size (rows, cols)
+     int *rows, *cols;
+{
+  if (rows)
+    *rows = _rl_screenheight;
+  if (cols)
+    *cols = _rl_screenwidth;
+}
+
 int
 _rl_init_terminal_io (terminal_name)
      const char *terminal_name;
 {
+#if defined (__DJGPP__)
+  _rl_screenwidth = ScreenCols () - 1;
+  _rl_screenheight = ScreenRows ();
+  _rl_screenchars = _rl_screenwidth * _rl_screenheight;
+  _rl_term_cr = "\r";
+  _rl_term_im = _rl_term_ei = _rl_term_ic = _rl_term_IC = (char *)NULL;
+  _rl_term_up = _rl_term_dc = _rl_term_DC = (char *)NULL;
+#if defined (HACK_TERMCAP_MOTION)
+  _rl_term_forward_char = (char *)NULL;
+#endif
+  _rl_terminal_can_insert = 0;
+#else  /* !__DJGPP__ */
   const char *term;
   char *buffer;
   int tty, tgetent_ret;
 
   term = terminal_name ? terminal_name : sh_get_env_value ("TERM");
@@ -570,50 +607,30 @@ _rl_init_terminal_io (terminal_name)
 
 #if defined (VI_MODE)
   bind_termcap_arrow_keys (vi_movement_keymap);
   bind_termcap_arrow_keys (vi_insertion_keymap);
 #endif /* VI_MODE */
+#endif /* !__DJGPP__ */
 
   return 0;
 }
 
-/* Bind the arrow key sequences from the termcap description in MAP. */
-static void
-bind_termcap_arrow_keys (map)
-     Keymap map;
-{
-  Keymap xkeymap;
-
-  xkeymap = _rl_keymap;
-  _rl_keymap = map;
-
-  rl_bind_keyseq_if_unbound (_rl_term_ku, rl_get_previous_history);
-  rl_bind_keyseq_if_unbound (_rl_term_kd, rl_get_next_history);
-  rl_bind_keyseq_if_unbound (_rl_term_kr, rl_forward_char);
-  rl_bind_keyseq_if_unbound (_rl_term_kl, rl_backward_char);
-
-  rl_bind_keyseq_if_unbound (_rl_term_kh, rl_beg_of_line);	/* Home */
-  rl_bind_keyseq_if_unbound (_rl_term_at7, rl_end_of_line);	/* End */
-
-  rl_bind_keyseq_if_unbound (_rl_term_kD, rl_delete);
-
-  _rl_keymap = xkeymap;
-}
-
 char *
 rl_get_termcap (cap)
      const char *cap;
 {
+#if !defined (__MSDOS__)
   register int i;
 
   if (tcap_initialized == 0)
     return ((char *)NULL);
   for (i = 0; i < NUM_TC_STRINGS; i++)
     {
       if (tc_strings[i].tc_var[0] == cap[0] && strcmp (tc_strings[i].tc_var, cap) == 0)
         return *(tc_strings[i].tc_value);
     }
+#endif /* !__MSDOS__ */
   return ((char *)NULL);
 }
 
 /* Re-initialize the terminal considering that the TERM/TERMCAP variable
    has changed. */
diff -aprNU5 gdb-7.12.1.orig/readline/tilde.c gdb-7.12.1/readline/tilde.c
--- gdb-7.12.1.orig/readline/tilde.c	2017-01-21 13:48:42 +0000
+++ gdb-7.12.1/readline/tilde.c	2019-02-24 16:06:12 +0000
@@ -194,11 +194,11 @@ tilde_expand (string)
 {
   char *result;
   int result_size, result_index;
 
   result_index = result_size = 0;
-  if (result = strchr (string, '~'))
+  if ((result = strchr (string, '~')))
     result = (char *)xmalloc (result_size = (strlen (string) + 16));
   else
     result = (char *)xmalloc (result_size = (strlen (string) + 1));
 
   /* Scan through STRING expanding tildes as we come to them. */
diff -aprNU5 gdb-7.12.1.orig/readline/tminit.c gdb-7.12.1/readline/tminit.c
--- gdb-7.12.1.orig/readline/tminit.c	1970-01-01 00:00:00 +0000
+++ gdb-7.12.1/readline/tminit.c	2019-02-24 16:06:12 +0000
@@ -0,0 +1,1532 @@
+/*
+ * tminit.c - initializer and main part of termios emulation.
+ *   designed for DJGPP by Daisuke Aoyama <jack@st.rim.or.jp>
+ *   special thanks to Ryo Shimizu
+ */
+
+#if defined (__DJGPP__)
+
+#include <libc/stubs.h>
+#include <conio.h>
+#include <fcntl.h>
+#include <go32.h>
+#include <io.h>
+#include <limits.h>
+#include <signal.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <termios.h>
+#include <unistd.h>
+#include <sys/farptr.h>
+#include <sys/fsext.h>
+#include <libc/bss.h>
+#include <libc/file.h>
+#include <libc/dosio.h>
+#include <libc/ttyprvt.h>
+#include <sys/version.h>
+
+#if __DJGPP_MINOR__ < 4
+# define _DEV_STDIN  0x0001
+# define _DEV_STDOUT 0x0002
+# define _DEV_NUL    0x0004
+# define _DEV_CLOCK  0x0008
+# define _DEV_RAW    0x0020
+# define _DEV_CDEV   0x0080
+# define _DEV_IOCTRL 0x4000
+#else
+# include <libc/getdinfo.h>
+#endif
+
+#define CPMEOF 0x1a /* Ctrl+Z */
+
+#define _REG_STATUS_CF 0x01
+#define _REG_STATUS_ZF 0x40
+#define _KEY_INS  0x80
+#define _KEY_CAPS 0x40
+#define _KEY_NUM  0x20
+#define _KEY_SCRL 0x10
+#define _KEY_ALT  0x08
+#define _KEY_CTRL 0x04
+#define _KEY_LSFT 0x02
+#define _KEY_RSFT 0x01
+#define _KEYE_SYSRQ 0x80
+#define _KEYE_CAPS  0x40
+#define _KEYE_NUM   0x20
+#define _KEYE_SCRL  0x10
+#define _KEYE_RALT  0x08
+#define _KEYE_RCTRL 0x04
+#define _KEYE_LALT  0x02
+#define _KEYE_LCTRL 0x01
+
+#define CHECKBYTES 32
+
+/* tty buffers */
+unsigned char __libc_tty_queue_buffer[_TTY_QUEUE_SIZE];
+struct tty __libc_tty_internal = TTYDEFAULT;
+struct tty *__libc_tty_p = &__libc_tty_internal;
+struct tty_editline __libc_tty_editline = { 0, { 0 }, { 0 }, };
+
+/* global only in the termios functions */
+int __libc_termios_hook_common_count = -1;
+
+/* static variables */
+static int __libc_use_function_and_arrow_keys = 0;
+static int __libc_has_enhanced_keyboard = 0;
+static int __libc_has_extended_keystroke = 0;
+static unsigned char __libc_extended_keystroke[16] = { 0, };
+static ssize_t __libc_termios_check_bytes = CHECKBYTES;
+
+/* static functions */
+static void __libc_termios_fflushall (void);
+static void __libc_termios_init_direct_functions (void);
+static ssize_t __libc_termios_read (int handle, void *buffer, size_t count, ssize_t *rv);
+static ssize_t __libc_termios_read_cooked_tty (int handle, void *buffer, size_t count);
+static ssize_t __libc_termios_read_raw_tty (int handle, void *buffer, size_t count);
+static ssize_t __libc_termios_write (int handle, const void *buffer, size_t count, ssize_t *rv);
+static ssize_t __libc_termios_write_cooked_tty (int handle, const void *buffer, size_t count);
+static ssize_t __libc_termios_write_raw_tty (int handle, const void *buffer, size_t count);
+static int __libc_termios_fsext (__FSEXT_Fnumber n, int *rv, va_list ap);
+static void __libc_termios_echo_ctrl (unsigned char ch);
+static void __libc_termios_maybe_echo_ctrl (unsigned char ch);
+static void __libc_termios_maybe_echo (unsigned char ch);
+static void __libc_termios_maybe_erase1 (void);
+static void __libc_termios_erase_editline (void);
+static void __libc_termios_kill_editline (void);
+static void __libc_termios_insert_editline (unsigned char ch);
+#if __DJGPP_MINOR__ < 4
+static int __libc_termios_exist_queue (void);
+#endif
+static void __libc_termios_clear_queue (void);
+static int __libc_termios_get_queue (void);
+static int __libc_termios_put_queue (unsigned char ch);
+static void __libc_termios_raise_signal (unsigned char ch, int sig);
+static void __libc_termios_fill_queue (void);
+
+/* direct I/O functions */
+static void __direct_add_keystroke (int c);
+static void __direct_add_keystrokes (char *s);
+static void __direct_check_extened_keystroke_at (int scan);
+/* AT keyboard */
+static int __direct_keysense_at (void);
+static unsigned char __direct_keyinput_at (void);
+static int __direct_ctrlsense_at (void);
+/* AT enhanced keyboard */
+static int __direct_keysense_ate (void);
+static unsigned char __direct_keyinput_ate (void);
+static int __direct_ctrlsense_ate (void);
+/* Output functions */
+static void __direct_output_tab_at (void);
+static void __direct_output_at (unsigned char ch);
+static void __direct_outputns_at (int n, const unsigned char *s);
+static void __direct_outputs_at (const unsigned char *s);
+/* function pointers */
+static int (*__direct_keysense) (void) = __direct_keysense_at;
+static unsigned char (*__direct_keyinput) (void) = __direct_keyinput_at;
+static int (*__direct_ctrlsense) (void) = __direct_ctrlsense_at;
+static void (*__direct_output) (unsigned char ch) = __direct_output_at;
+static void (*__direct_outputns) (int n, const unsigned char *s) = __direct_outputns_at;
+static void (*__direct_outputs) (const unsigned char *s) = __direct_outputs_at;
+
+/******************************************************************************/
+/* initialize function ********************************************************/
+
+static void
+__libc_termios_fflushall (void)
+{
+#if 0 /* don't work on djgpp */
+  fflush (NULL);
+#else
+  _fwalk ((void (*) (FILE*)) fflush);
+#endif
+}
+
+static void
+__libc_termios_init_direct_functions (void)
+{
+  __libc_has_enhanced_keyboard = 0;
+  __libc_has_extended_keystroke = 0;
+
+  if (_farpeekb (_dos_ds, 0x496) & 0x10)
+    __libc_has_enhanced_keyboard = 1;
+
+  if (__libc_has_enhanced_keyboard)
+    {
+      __direct_keysense = __direct_keysense_ate;
+      __direct_keyinput = __direct_keyinput_ate;
+      __direct_ctrlsense = __direct_ctrlsense_ate;
+    }
+  else
+    {
+      __direct_keysense = __direct_keysense_at;
+      __direct_keyinput = __direct_keyinput_at;
+      __direct_ctrlsense = __direct_ctrlsense_at;
+    }
+  __direct_output = __direct_output_at;
+  __direct_outputs = __direct_outputs_at;
+}
+
+void
+__libc_termios_init (void)
+{
+  if (__libc_termios_hook_common_count != __bss_count)
+    {
+      __libc_termios_hook_common_count = __bss_count;
+
+      /* flush all buffered streams */
+      __libc_termios_fflushall ();
+
+      /* check enhanced keyboard, etc */
+      __libc_termios_init_direct_functions ();
+
+      /* set special hooks */
+      __libc_read_termios_hook = __libc_termios_read;
+      __libc_write_termios_hook = __libc_termios_write;
+
+      /* import parameters */
+      /* __libc_tty_p = ...; */
+
+      /* fsext */
+      (void) __FSEXT_set_function (0, __libc_termios_fsext);
+      (void) __FSEXT_set_function (1, __libc_termios_fsext);
+      (void) __FSEXT_set_function (2, __libc_termios_fsext);
+      __libc_termios_check_bytes = CHECKBYTES;
+    }
+}
+
+int
+__libc_termios_disable_function_and_arrow_keys (void)
+{
+  int old_value;
+
+  old_value = __libc_use_function_and_arrow_keys;
+  __libc_use_function_and_arrow_keys = 0;
+
+  return old_value;
+}
+
+int
+__libc_termios_enable_function_and_arrow_keys (void)
+{
+  int old_value;
+
+  old_value = __libc_use_function_and_arrow_keys;
+  __libc_use_function_and_arrow_keys = 1;
+
+  return old_value;
+}
+
+/******************************************************************************/
+/* direct I/O function ********************************************************/
+
+/* function key trans function */
+static void
+__direct_add_keystroke (int c)
+{
+  if (__libc_has_extended_keystroke + 1 > sizeof (__libc_extended_keystroke))
+    return;
+
+  __libc_extended_keystroke[__libc_has_extended_keystroke++] = (unsigned char) c;
+}
+
+static void
+__direct_add_keystrokes (char *s)
+{
+  int len;
+
+  len = strlen (s);
+  if (__libc_has_extended_keystroke + len > sizeof (__libc_extended_keystroke))
+    return;
+
+  while (--len >= 0)
+    __libc_extended_keystroke[__libc_has_extended_keystroke++] = (unsigned char) s[len];
+}
+
+#define _NDUMMY (0xffU)
+#define _N(c) (0x00U|(c)) /* no shift */
+#define _S(c) (0x40U|(c)) /* w/shift */
+#define _C(c) (0x80U|(c)) /* w/ctrl */
+#define _A(c) (0xc0U|(c)) /* w/alt */
+#define _TRANS_NOSHIFT "\x1b[0"
+#define _TRANS_SHIFT "\x1b[1"
+#define _TRANS_CTRL "\x1b[2"
+#define _TRANS_ALT "\x1b[3"
+
+static unsigned char trans_alphabet_chars[64] =
+"ABCDEFGHIJKLMNOPQRSTUVWXYZ123456ABCDEFGHIJKLMNOPQRSTUVWXYZ123456";
+
+static unsigned char trans_mapping_chras_at[] =
+{
+  /* 000-037: A-Z, 040-077: XA-XZ */
+  _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, /* 00-07 */
+  _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, /* 08-0F */
+  _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, /* 10-17 */
+  _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, /* 18-1F */
+  _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, /* 20-27 */
+  _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, /* 28-2F */
+  _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, /* 30-37 */
+  _NDUMMY, _NDUMMY, _NDUMMY, _N(040), _N(041), _N(042), _N(043), _N(044), /* 38-3F */
+  _N(045), _N(046), _N(047), _N(050), _N(051), _NDUMMY, _NDUMMY, _N(006), /* 40-47 */
+  _N(000), _N(010), _NDUMMY, _N(001), _NDUMMY, _N(002), _NDUMMY, _N(007), /* 48-4F */
+  _N(003), _N(011), _N(004), _N(005), _S(040), _S(041), _S(042), _S(043), /* 50-57 */
+  _S(044), _S(045), _S(046), _S(047), _S(050), _S(051), _C(040), _C(041), /* 58-5F */
+  _C(042), _C(043), _C(044), _C(045), _C(046), _C(047), _C(050), _C(051), /* 60-67 */
+  _A(040), _A(041), _A(042), _A(043), _A(044), _A(045), _A(046), _A(047), /* 68-6F */
+  _A(050), _A(051), _NDUMMY, _C(001), _C(002), _C(007), _C(011), _C(006), /* 70-77 */
+  _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, /* 78-7F */
+  _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _C(010), _N(052), _N(053), _S(052), /* 80-87 */
+  _S(053), _C(052), _C(053), _A(052), _A(053), _C(000), _NDUMMY, _NDUMMY, /* 88-8F */
+  _NDUMMY, _C(003), _C(004), _C(005), _NDUMMY, _NDUMMY, _NDUMMY, _A(006), /* 90-97 */
+  _A(000), _A(010), _NDUMMY, _A(001), _NDUMMY, _A(002), _NDUMMY, _A(007), /* 98-9F */
+  _A(003), _A(011), _A(004), _A(005), _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, /* A0-A7 */
+  _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, /* A8-AF */
+  _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, /* B0-B7 */
+  _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, /* B8-BF */
+  _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, /* C0-C7 */
+  _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, /* C8-CF */
+  _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, /* D0-D7 */
+  _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, /* D8-DF */
+  _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, /* E0-E7 */
+  _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, /* E8-EF */
+  _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, /* F0-F7 */
+  _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, /* F8-FF */
+};
+
+static void
+__direct_check_extened_keystroke_at (int scan)
+{
+  int c, shift;
+
+  if (!__libc_use_function_and_arrow_keys || scan < 0 || scan > 0xff)
+    return;
+
+  c = (int) trans_mapping_chras_at[scan];
+  if (c == (int) _NDUMMY)
+    return;
+
+  shift = c & 0xc0;
+  c &= ~0xc0;
+  __direct_add_keystroke (trans_alphabet_chars[c]);
+  if (c >= 040)
+    __direct_add_keystroke ('X');
+  if (shift == 0x00)
+    __direct_add_keystrokes (_TRANS_NOSHIFT);
+  else if (shift == 0x40)
+    __direct_add_keystrokes (_TRANS_SHIFT);
+  else if (shift == 0x80)
+    __direct_add_keystrokes (_TRANS_CTRL);
+  else if (shift == 0xc0)
+    __direct_add_keystrokes (_TRANS_ALT);
+}
+
+/* Input form AT keyboard */
+static int
+__direct_keysense_at (void)
+{
+  __dpmi_regs r;
+
+  if (__libc_has_extended_keystroke)
+    return 1;
+
+  r.h.ah = 0x01;
+  __dpmi_int (0x16, &r);
+  if (r.x.flags & _REG_STATUS_ZF)
+    return 0;
+
+  return 1;
+}
+
+static unsigned char
+__direct_keyinput_at (void)
+{
+  __dpmi_regs r;
+
+  if (__libc_has_extended_keystroke)
+    return __libc_extended_keystroke[--__libc_has_extended_keystroke];
+
+  r.h.ah = 0x00;
+  __dpmi_int (0x16, &r);
+  if (r.h.al != 0x00)
+    return r.h.al;
+
+  __direct_check_extened_keystroke_at (r.h.ah);
+  if (__libc_has_extended_keystroke)
+    return __libc_extended_keystroke[--__libc_has_extended_keystroke];
+
+  return 0;
+}
+
+static int
+__direct_ctrlsense_at (void)
+{
+  __dpmi_regs r;
+
+  if (__libc_has_extended_keystroke)
+    return 0;
+
+  r.h.ah = 0x02;
+  __dpmi_int (0x16, &r);
+  if (r.h.al & _KEY_CTRL)
+    return 1;
+
+  return 0;
+}
+
+/* Input from AT enhanced keyboard */
+static int
+__direct_keysense_ate (void)
+{
+  __dpmi_regs r;
+
+  if (__libc_has_extended_keystroke)
+    return 1;
+
+  r.h.ah = 0x11;
+  __dpmi_int (0x16, &r);
+  if (r.x.flags & _REG_STATUS_ZF)
+    return 0;
+
+  return 1;
+}
+
+static unsigned char
+__direct_keyinput_ate (void)
+{
+  __dpmi_regs r;
+
+  if (__libc_has_extended_keystroke)
+    return __libc_extended_keystroke[--__libc_has_extended_keystroke];
+
+  r.h.ah = 0x10;
+  __dpmi_int (0x16, &r);
+  if (r.h.al != 0x00 && (r.h.al < 0xe0U
+			 || (r.h.al != 0xe0 && r.h.al != 0xf0)))
+    return r.h.al;
+
+  __direct_check_extened_keystroke_at (r.h.ah);
+  if (__libc_has_extended_keystroke)
+    return __libc_extended_keystroke[--__libc_has_extended_keystroke];
+
+  return 0;
+}
+
+static int
+__direct_ctrlsense_ate (void)
+{
+  __dpmi_regs r;
+
+  if (__libc_has_extended_keystroke)
+    return 0;
+
+  r.h.ah = 0x12;
+  __dpmi_int (0x16, &r);
+  if (r.h.al & _KEY_CTRL) /* either CTRL */
+    return 1;
+
+  return 0;
+}
+
+/* output to Screen */
+static void
+__direct_output_tab_at (void)
+{
+  __dpmi_regs r;
+  int page, col;
+  int x, y;
+
+  page = _farpeekb (_dos_ds, 0x462);
+  col = _farpeekw (_dos_ds, 0x44a);
+
+  r.h.ah = 3;
+  r.h.bh = page;
+  __dpmi_int (0x10, &r);
+  x = r.h.dl;
+  y = r.h.dh;
+
+  x += 8;
+  x &= ~7;
+  if (x > col)
+    {
+#if 1
+      r.h.al = '\r';
+      __dpmi_int (0x29, &r);
+      r.h.al = '\n';
+      __dpmi_int (0x29, &r);
+#else
+      (void) putch ('\r');
+      (void) putch ('\n');
+#endif
+    }
+  else
+    {
+      r.h.ah = 2;
+      r.h.bh = page;
+      r.h.dl = x;
+      r.h.dh = y;
+      __dpmi_int (0x10, &r);
+    }
+}
+
+static void
+__direct_output_at (unsigned char ch)
+{
+#if 1
+  __dpmi_regs r;
+#endif
+
+  if (ch == 0x09)
+    {
+      __direct_output_tab_at ();
+      return;
+    }
+  else if (ch == 0xff)
+    return;
+
+#if 1
+  r.h.al = ch;
+  __dpmi_int (0x29, &r);
+#else
+  (void) putch (ch);
+#endif
+}
+
+static void
+__direct_outputns_at (int n, const unsigned char *s)
+{
+#if 1
+  __dpmi_regs r;
+#endif
+  unsigned char ch;
+
+  while (--n >= 0)
+    {
+      ch = *s++;
+      if (ch == 0x09)
+	__direct_output_tab_at ();
+      else if (ch != 0xff)
+	{
+#if 1
+	  r.h.al = ch;
+	  __dpmi_int (0x29, &r);
+#else
+	  (void) putch (ch);
+#endif
+	}
+    }
+}
+
+static void
+__direct_outputs_at (const unsigned char *s)
+{
+  while (*s)
+    __direct_output_at (*s++);
+}
+
+/******************************************************************************/
+/* special read function ******************************************************/
+
+static ssize_t
+__libc_termios_read (int handle, void *buffer, size_t count, ssize_t *rv)
+{
+  short devmod;
+  ssize_t bytes;
+
+  /* check handle whether valid or not */
+  devmod = _get_dev_info (handle);
+  if (devmod == -1)
+    {
+      *rv = -1;
+      return 1;
+    }
+
+  /* special case */
+  if (count == 0)
+    {
+      *rv = 0;
+      return 1;
+    }
+
+  /* console only... */
+  if ((devmod & _DEV_CDEV) && (devmod & (_DEV_STDIN|_DEV_STDOUT)))
+    {
+      /* character device */
+      if (devmod & _DEV_RAW)
+	*rv = __libc_termios_read_raw_tty (handle, buffer, count);
+      else
+	*rv = __libc_termios_read_cooked_tty (handle, buffer, count);
+      return 1;
+    }
+
+  if (__file_handle_modes[handle] & O_BINARY)
+    {
+      bytes = _read (handle, buffer, count);
+      if (bytes < 0)
+	{
+	  *rv = -1;
+	  return 1;
+	}
+    }
+  else
+    {
+      unsigned char *rp, *wp;
+      ssize_t n;
+
+      bytes = _read (handle, buffer, count);
+      if (bytes < 0)
+	{
+	  *rv = -1;
+	  return 1;
+	}
+
+      rp = wp = buffer;
+      n = bytes;
+      while (--n >= 0)
+	{
+	  unsigned char ch;
+
+	  ch = *rp++;
+	  if (ch == CPMEOF)
+	    {
+	      ++n;
+	      (void) lseek (handle, -n, SEEK_CUR);
+	      break;
+	    }
+	  else if (ch == '\r')
+	    {
+	      if (n > 0)
+		{
+		  /* peek next character */
+		  if (*rp == '\n')
+		    {
+		      /* if found '\n', delete '\r' */
+		      ch = *rp++;
+		      --n;
+		    }
+		}
+	      else
+		{
+		  unsigned char tmpch;
+
+		  /* read a character to peek */
+		  if (_read (handle, &tmpch, 1) == 1)
+		    {
+		      if (tmpch == '\n')
+			ch = tmpch;
+		      else
+			(void) lseek (handle, -1, SEEK_CUR);
+		    }
+		}
+	    }
+	  *wp++ = ch;
+	}
+      bytes = wp - (unsigned char *) buffer;
+    }
+
+  /* result of read() */
+  *rv =  bytes;
+  return 1;
+}
+
+static ssize_t
+__libc_termios_read_cooked_tty (int handle, void *buffer, size_t count)
+{
+  unsigned char *wp;
+  ssize_t n;
+
+  wp = buffer;
+  n = count;
+
+#if 0
+  /* clear cooked queue */
+  if (__libc_termios_exist_queue ())
+    __libc_termios_clear_queue ();
+#endif
+
+  if (__libc_tty_p->t_lflag & ICANON)
+    {
+      /* get inputs (wait for NL or EOT) */
+      if (! __libc_termios_exist_queue ())
+	__libc_termios_fill_queue ();
+
+      while (--n >= 0)
+	{
+	  if (! __libc_termios_exist_queue ())
+	    break;
+
+	  *wp++ = __libc_termios_get_queue ();
+	}
+    }
+  else
+    {
+      /* block until getting inputs */
+      while (! __libc_termios_exist_queue ())
+	{
+	  __dpmi_yield ();
+	  __libc_termios_fill_queue ();
+	}
+
+      while (--n >= 0)
+	{
+	  *wp++ = __libc_termios_get_queue ();
+
+	  if (! __libc_termios_exist_queue ())
+	    {
+	      __libc_termios_fill_queue ();
+	      if (! __libc_termios_exist_queue ())
+		break;
+	    }
+	}
+    }
+
+  return (ssize_t) (wp - (unsigned char *) buffer);
+}
+
+static ssize_t
+__libc_termios_read_raw_tty (int handle, void *buffer, size_t count)
+{
+  unsigned char *wp;
+  unsigned char ch;
+  ssize_t n;
+
+  n = count;
+  wp = buffer;
+
+  /* clear cooked queue */
+  if (__libc_termios_exist_queue ())
+    __libc_termios_clear_queue ();
+
+  /* block until getting inputs */
+  while (! __direct_keysense ())
+    __dpmi_yield ();
+
+  while (--n >= 0)
+    {
+      /* exhaust inputs ? */
+      if (! __direct_keysense ())
+	break;
+
+      /* realy get */
+      ch = __direct_keyinput ();
+
+      /* replace CTRL+SPACE with 0x00 */
+      if (ch == ' ' && __direct_ctrlsense ())
+	ch = '\0';
+
+      /* copy a character into buffer and echo */
+      *wp++ = ch;
+      __libc_termios_maybe_echo (ch);
+    }
+
+  return (ssize_t) (wp - (unsigned char *) buffer);
+}
+
+/******************************************************************************/
+/* special write function *****************************************************/
+
+static unsigned char __libc_termios_write_sbuf_internal[64];
+static unsigned char *__libc_termios_write_sbuf = NULL;
+static size_t __libc_termios_write_sbuflen = 0;
+static int __libc_termios_write_count = -1;
+
+void
+__libc_termios_check_signals (void);
+
+static ssize_t
+__libc_termios_write (int handle, const void *buffer, size_t count, ssize_t *rv)
+{
+  short devmod;
+  ssize_t bytes;
+
+  /* check handle whether valid or not */
+  devmod = _get_dev_info (handle);
+  if (devmod == -1)
+    {
+      *rv = -1;
+      return 1;
+    }
+
+  /* special case */
+  if (count == 0)
+    {
+      *rv = 0;
+      return 1;
+    }
+
+  /* console only... */
+  if ((devmod & _DEV_CDEV) && (devmod & (_DEV_STDIN|_DEV_STDOUT)))
+    {
+      /* character device */
+      if (devmod & _DEV_RAW)
+	*rv = __libc_termios_write_raw_tty (handle, buffer, count);
+      else
+	*rv = __libc_termios_write_cooked_tty (handle, buffer, count);
+      return 1;
+    }
+
+  if (__file_handle_modes[handle] & O_BINARY)
+    {
+      bytes = _write (handle, buffer, count);
+      if (bytes < 0)
+	{
+	  *rv = -1;
+	  return 1;
+	}
+    }
+  else
+    {
+      const unsigned char *rp;
+      unsigned char *tp, *ep;
+      ssize_t n;
+
+      /* initialize local buffer */
+      if (__libc_termios_write_count != __bss_count)
+	{
+	  __libc_termios_write_count = __bss_count;
+	  __libc_termios_write_sbuflen = _go32_info_block.size_of_transfer_buffer;
+	  __libc_termios_write_sbuf = malloc (__libc_termios_write_sbuflen);
+	  if (__libc_termios_write_sbuf == NULL)
+	    {
+	      __libc_termios_write_sbuf = &__libc_termios_write_sbuf_internal[0];
+	      __libc_termios_write_sbuflen = sizeof (__libc_termios_write_sbuf_internal);
+	    }
+	}
+
+      rp = buffer;
+      tp = __libc_termios_write_sbuf;
+      ep = tp + __libc_termios_write_sbuflen;
+      n = count;
+      bytes = 0;
+      while (n >= 0)
+	{
+	  unsigned char *wp;
+	  unsigned char ch;
+	  ssize_t ncr, wbytes;
+
+	  /* fill local buffer */
+	  wp = tp;
+	  ncr = 0;
+	  while ((wp < ep) && (--n >= 0))
+	    {
+	      /* get character */
+	      ch = *rp++;
+
+	      /* LF conversion */
+	      if (ch == '\n')
+		{
+		  if (wp == (ep - 1))
+		    {
+		      n++;
+		      rp--;
+		      break;
+		    }
+		  *wp++ = '\r';
+		  ncr++;
+		}
+
+	      /* put character */
+	      *wp++ = ch;
+	    }
+
+	  /* write on handle */
+	  wbytes = _write (handle, tp, (size_t) (wp - tp));
+	  if (wbytes < 0)
+	    {
+	      *rv = -1;
+	      return 1;
+	    }
+	  if (wbytes < (ssize_t) (wp - tp))
+	    {
+	      /* detected disk full, but the result is not reality */
+	      *rv = bytes + (wbytes > ncr ? wbytes - ncr : 0);
+	      return 1;
+	    }
+
+	  /* don't count CR */
+	  bytes += wbytes - ncr;
+	}
+    }
+
+  __libc_termios_check_bytes -= bytes;
+  if (__libc_termios_check_bytes <= 0)
+    {
+      __libc_termios_check_bytes = CHECKBYTES;
+      __libc_termios_check_signals ();
+    }
+
+  /* result of write() */
+  *rv =  bytes;
+  return 1;
+}
+
+static ssize_t
+__libc_termios_write_cooked_tty (int handle, const void *buffer, size_t count)
+{
+  ssize_t bytes;
+
+  /* output process if need */
+  if (__libc_tty_p->t_oflag & OPOST)
+    {
+      const unsigned char *rp;
+      unsigned char ch;
+      ssize_t n, nn;
+
+      rp = buffer;
+      n = count;
+      while (n > 0)
+	{
+	  nn = (n < __libc_termios_check_bytes) ? n : __libc_termios_check_bytes;
+	  n -= nn;
+	  __libc_termios_check_bytes -= nn;
+
+	  while (--nn >= 0)
+	    {
+	      /* get character */
+	      ch = *rp++;
+
+	      /* NOTE: multibyte character don't contain control character */
+	      /* map NL to CRNL */
+	      if (ch == '\n' && (__libc_tty_p->t_oflag & ONLCR))
+		__direct_output ('\r');
+	      /* map CR to NL */
+	      else if (ch == '\r' && (__libc_tty_p->t_oflag & OCRNL))
+		ch = '\n';
+
+	      __direct_output (ch);
+	    }
+
+	  if (__libc_termios_check_bytes <= 0)
+	    {
+	      __libc_termios_check_bytes = CHECKBYTES;
+	      __libc_termios_check_signals ();
+	    }
+	}
+
+      /* don't count CR */
+      bytes = count;
+    }
+  else
+    {
+      /* output with no effect */
+      bytes = __libc_termios_write_raw_tty (handle, buffer, count);
+    }
+
+  return bytes;
+}
+
+static ssize_t
+__libc_termios_write_raw_tty (int handle, const void *buffer, size_t count)
+{
+  const unsigned char *rp;
+  ssize_t n;
+
+  rp = buffer;
+  n = count;
+  while (n > 0)
+    {
+      if (n < __libc_termios_check_bytes)
+	{
+	  __libc_termios_check_bytes -= n;
+	  __direct_outputns (n, rp);
+	  rp += n;
+	  break;
+	}
+      else
+	{
+	  n -= __libc_termios_check_bytes;
+	  __direct_outputns (__libc_termios_check_bytes, rp);
+	  rp += __libc_termios_check_bytes;
+	  __libc_termios_check_bytes = CHECKBYTES;
+	  __libc_termios_check_signals ();
+	}
+    }
+
+  return count;
+}
+
+/******************************************************************************/
+/* special fsext function *****************************************************/
+
+static int
+__libc_termios_fsext (__FSEXT_Fnumber n, int *rv, va_list ap)
+{
+  short devmod;
+  ssize_t bytes;
+  int handle;
+
+  handle = va_arg (ap, int);
+  devmod = _get_dev_info (handle);
+  if (devmod == -1)
+    return 0;
+  if (!(devmod & _DEV_CDEV) || !(devmod & (_DEV_STDIN|_DEV_STDOUT)))
+    return 0;
+
+  /* console only... */
+  switch (n)
+    {
+#if 0
+    case __FSEXT_read:
+      {
+	void *buffer;
+	size_t count;
+
+	buffer = va_arg (ap, void *);
+	count = va_arg (ap, size_t);
+	if (devmod & _DEV_RAW)
+	  bytes = __libc_termios_read_raw_tty (handle, buffer, count);
+	else
+	  bytes = __libc_termios_read_cooked_tty (handle, buffer, count);
+
+	/* result of read */
+	*rv = bytes;
+	return 1;
+      }
+    case __FSEXT_write:
+      {
+	const void *buffer;
+	size_t count;
+
+	buffer = va_arg (ap, const void *);
+	count = va_arg (ap, size_t);
+	if (devmod & _DEV_RAW)
+	  bytes = __libc_termios_write_raw_tty (handle, buffer, count);
+	else
+	  bytes = __libc_termios_write_cooked_tty (handle, buffer, count);
+
+	/* result of write */
+	*rv = bytes;
+	return 1;
+      }
+#else
+    case __FSEXT_write:
+      {
+	size_t count;
+	const void *buffer;
+
+	buffer = va_arg (ap, const void *);
+	count = va_arg (ap, size_t);
+	bytes = __libc_termios_write_raw_tty (handle, buffer, count);
+
+	/* result of write */
+	*rv = bytes;
+	return 1;
+      }
+#endif
+    default:
+      break;
+    }
+
+  return 0;
+}
+
+/******************************************************************************/
+/* echo routines **************************************************************/
+
+static void
+__libc_termios_echo_ctrl (unsigned char ch)
+{
+  ch ^= 0x40;
+  __direct_output ('^');
+  __direct_output (ch);
+}
+
+static void
+__libc_termios_maybe_echo_ctrl (unsigned char ch)
+{
+  if (__libc_tty_p->t_lflag & ECHOCTL)
+    __libc_termios_echo_ctrl (ch);
+}
+
+static void
+__libc_termios_maybe_echo (unsigned char ch)
+{
+  if (! (__libc_tty_p->t_lflag & ECHO))
+    {
+      /* don't echo but newline is required ? */
+      if (ch == '\n' && (__libc_tty_p->t_lflag & ECHONL))
+	{
+	  if (__libc_tty_p->t_oflag & ONLCR)
+	    __direct_output ('\r');
+	  __direct_output ('\n');
+	}
+      return;
+    }
+
+  /* check literal flag */
+  if ((__libc_tty_p->t_status & _TS_LNCH) && (ch < 0x20))
+    {
+      __libc_termios_echo_ctrl (ch);
+      return;
+    }
+
+  /* output process if need */
+  if (__libc_tty_p->t_oflag & OPOST)
+    {
+      /* map NL to CRNL */
+      if (ch == '\n' && (__libc_tty_p->t_oflag & ONLCR))
+	{
+	  __direct_output ('\r');
+	  __direct_output ('\n');
+	  return;
+	}
+      /* map CR to NL */
+      else if (ch == '\r' && (__libc_tty_p->t_oflag & OCRNL))
+	{
+	  __direct_output ('\n');
+	  return;
+	}
+      /* discard EOT */
+      else if (_CC_EQU (VEOF, ch) && (__libc_tty_p->t_oflag & ONOEOT))
+	{
+	  return;
+	}
+    }
+
+  /* control character except newline */
+  if ((ch < 0x20 || ch == 0x7f) && (__libc_tty_p->t_lflag & ECHOCTL) && ch != '\n')
+    {
+      __libc_termios_echo_ctrl (ch);
+      return;
+    }
+
+  /* no effect */
+  __direct_output (ch);
+}
+
+/******************************************************************************/
+/* edit routines **************************************************************/
+
+static void
+__libc_termios_maybe_erase1 (void)
+{
+  if (__libc_tty_p->t_lflag & ECHO)
+    {
+      /* eat prev. character by BS SPC BS */
+      __direct_output ('\010');
+      if (__libc_tty_p->t_lflag & ECHOE)
+	{
+	  __direct_output (' ');
+	  __direct_output ('\010');
+	}
+    }
+}
+
+/* erase one prev. character of editline */
+static void
+__libc_termios_erase_editline (void)
+{
+  int col;
+  char pf;
+
+  col = __libc_tty_editline.col;
+  if (col == 0) /* no more */
+    return;
+
+  /* get position flag */
+  pf = __libc_tty_editline.flag[col - 1];
+  if (pf == _TTY_EDITLINE_INVALID || pf < 0)
+    {
+      /* erase all invalid character */
+      while (col > 0 && __libc_tty_editline.flag[col - 1] < 0)
+	{
+	  __libc_termios_maybe_erase1 ();
+	  --col;
+	}
+    }
+  else if (pf == _TTY_EDITLINE_CTRL)
+    {
+      if (__libc_tty_p->t_lflag & ECHOCTL)
+	{
+	  /* erase one of "^X" */
+	  __libc_termios_maybe_erase1 ();
+	  --col;
+	}
+      __libc_termios_maybe_erase1 ();
+      --col;
+    }
+  else
+    {
+      /* erase single or multibyte charcter */
+      while (--pf >= 0)
+	{
+	  __libc_termios_maybe_erase1 ();
+	  --col;
+	}
+    }
+
+  /* set next insert position */
+  __libc_tty_editline.col = col;
+}
+
+/* erase all editline */
+static void
+__libc_termios_kill_editline (void)
+{
+  if (__libc_tty_p->t_lflag & ECHOKE)
+    {
+      while (__libc_tty_editline.col != 0)
+	__libc_termios_erase_editline ();
+    }
+  else
+    __libc_tty_editline.col = 0;
+
+  if (__libc_tty_p->t_lflag & ECHOK)
+    __libc_termios_maybe_echo ('\n');
+}
+
+static void
+__libc_termios_insert_editline (unsigned char ch)
+{
+  int mbsize;
+  int col;
+
+  col = __libc_tty_editline.col;
+  if (col >= _TTY_EDITLINE_SIZE)
+    {
+      /* detected over flow */
+      if (__libc_tty_p->t_iflag & IMAXBEL)
+	__direct_output ('\007');
+      return;
+    }
+
+  __libc_tty_editline.buf[col] = ch;
+  if (col == 0 || ((col > 0)
+		   && __libc_tty_editline.flag[col - 1] != _TTY_EDITLINE_INVALID))
+    {
+      /* check multibyte length */
+      mbsize = mblen (__libc_tty_editline.buf + col, 1);
+      if (mbsize == 1)
+	{
+	  /* single character */
+	  if ((ch < 0x20) || ch == 0x7f)
+	    __libc_tty_editline.flag[col] = _TTY_EDITLINE_CTRL;
+	  else
+	    __libc_tty_editline.flag[col] = _TTY_EDITLINE_SINGLE;
+	  __libc_termios_maybe_echo (ch);
+	}
+      else
+	{
+	  /* first of multibyte or invalid character */
+	  __libc_tty_editline.flag[col] = _TTY_EDITLINE_INVALID;
+	  __libc_tty_p->t_status |= _TS_LNCH;
+	}
+    }
+  else
+    {
+      int pcol;
+
+      /* look for non fixed flag */
+      pcol = col;
+      while (__libc_tty_editline.flag[pcol - 1] == _TTY_EDITLINE_INVALID)
+	if (--pcol <= 0)
+	  break;
+
+      /* check whether it's multibyte sequence */
+      mbsize = mblen (__libc_tty_editline.buf + pcol, (col - pcol + 1));
+      if (mbsize > 1)
+	{
+	  /* multibyte sequence is good */
+	  while (pcol < col)
+	    {
+	      /* set negative size for dividing sequence */
+	      __libc_tty_editline.flag[pcol] = -mbsize;
+	      __libc_termios_maybe_echo (__libc_tty_editline.buf[pcol]);
+	      pcol++;
+	    }
+	  /* last flag is always positive size */
+	  __libc_tty_editline.flag[col] = mbsize;
+	  __libc_termios_maybe_echo (ch);
+	}
+      else
+	{
+	  if ((col - pcol + 1) > MB_CUR_MAX)
+	    {
+	      /* it's terrible... */
+	      while (pcol <= col)
+		{
+		  /* replace all with valid character */
+		  __libc_tty_editline.flag[pcol] = _TTY_EDITLINE_SINGLE;
+		  __libc_tty_editline.buf[pcol] = 'X';
+		  __libc_termios_maybe_echo ('X');
+		  pcol++;
+		}
+	    }
+
+	  /* continuous multibyte character */
+	  __libc_tty_editline.flag[col] = _TTY_EDITLINE_INVALID;
+	  __libc_tty_p->t_status |= _TS_LNCH;
+	}
+    }
+
+  /* set next insert position */
+  col++;
+  __libc_tty_editline.col = col;
+}
+
+/******************************************************************************/
+/* queued input routines ******************************************************/
+
+#if __DJGPP_MINOR__ < 4
+static int
+#else
+int
+#endif
+__libc_termios_exist_queue (void)
+{
+  return __libc_tty_p->t_count;
+}
+
+static void
+__libc_termios_clear_queue (void)
+{
+  __libc_tty_p->t_count = 0;
+  __libc_tty_p->t_rpos = __libc_tty_p->t_top;
+  __libc_tty_p->t_wpos = __libc_tty_p->t_top;
+}
+
+static int
+__libc_termios_get_queue (void)
+{
+  int ch;
+
+  if (__libc_tty_p->t_count == 0)
+    return -1;
+
+  ch = *__libc_tty_p->t_rpos++;
+  __libc_tty_p->t_count--;
+
+  if (__libc_tty_p->t_rpos >= __libc_tty_p->t_bottom)
+    __libc_tty_p->t_rpos = __libc_tty_p->t_top;
+
+  return ch;
+}
+
+static int
+__libc_termios_put_queue (unsigned char ch)
+{
+  if (__libc_tty_p->t_count >= __libc_tty_p->t_size)
+    return -1;
+
+  *__libc_tty_p->t_wpos++ = ch;
+  __libc_tty_p->t_count++;
+
+  if (__libc_tty_p->t_wpos >= __libc_tty_p->t_bottom)
+    __libc_tty_p->t_wpos = __libc_tty_p->t_top;
+
+  return 0;
+}
+
+static void
+__libc_termios_raise_signal (unsigned char ch, int sig)
+{
+#if 0
+  struct sigaction oldact;
+
+  if (sigaction (sig, NULL, &oldact) == 0)
+    if (oldact.sa_handler == SIG_DFL)
+      __libc_termios_maybe_echo_ctrl (ch);
+#else
+  __libc_termios_maybe_echo_ctrl (ch);
+#endif
+  kill (getpid(), sig);
+}
+
+static void
+__libc_termios_fill_queue (void)
+{
+  unsigned char ch;
+
+  while (1)
+    {
+      /* exhaust inputs ? */
+      if (! __direct_keysense ())
+	{
+	  __dpmi_yield ();
+	  /* wait for NL or EOT ? */
+	  if (__libc_tty_p->t_lflag & ICANON)
+	    continue;
+	  return;
+	}
+
+      /* realy get */
+      ch = __direct_keyinput ();
+
+      /* replace CTRL+SPACE with 0x00 */
+      if (ch == ' ' && __direct_ctrlsense ())
+	ch = '\0';
+
+      /* input process if need */
+      if (! (__libc_tty_p->t_status & _TS_LNCH) || ch != (unsigned char) _POSIX_VDISABLE)
+	{
+	  /* software signals */
+	  if (__libc_tty_p->t_lflag & ISIG)
+	    {
+	      if (! (__libc_tty_p->t_iflag & IGNBRK) && _CC_EQU (VINTR, ch))
+		{
+		  if (__libc_tty_p->t_iflag & BRKINT)
+		    {
+		      __libc_termios_raise_signal (ch, SIGINT);
+		      continue;
+		    }
+		  else
+		    {
+		      ch = '\0';
+		      goto proc_skip;
+		    }
+		}
+	      else if (_CC_EQU (VQUIT, ch))
+		{
+		  __libc_termios_raise_signal (ch, SIGQUIT);
+		  continue;
+		}
+	      else if (_CC_EQU (VSUSP, ch))
+		{
+#ifdef SIGTSTP
+		  __libc_termios_raise_signal (ch, SIGTSTP);
+#else /* djgpp don't have ... */
+		  {
+		    char oldcwd[PATH_MAX];
+		    int fds[5] = { -1, -1, -1, -1, -1 };
+		    int i;
+
+		    for (i = 0; i < 5; i++)
+		      if ((fds[i] = fcntl (i, F_DUPFD, 20)) < 0)
+		        __direct_outputs ("Suspend: cannot save fds\r\n");
+
+		    __direct_outputs ("\r\nSuspended\r\n");
+		    /* keep cwd on exec */
+		    getcwd (oldcwd, sizeof (oldcwd));
+		    system (NULL);
+		    chdir (oldcwd);
+
+		    for (i = 0; i < 5; i++)
+		      if (fds[i] >= 0)
+			{
+			  dup2 (fds[i], i);
+			  close (fds[i]);
+			}
+		  }
+#endif /* !SIGTSTP */
+		  continue;
+		}
+	    }
+
+	  /* flow control... */
+	  if (_CC_EQU (VSTART, ch) && (__libc_tty_p->t_iflag & IXOFF))
+	    {
+	      continue;
+	    }
+	  else if (_CC_EQU (VSTOP, ch) && (__libc_tty_p->t_iflag & IXOFF))
+	    {
+	      continue;
+	    }
+
+	  /* CR/LF process */
+	  if (ch == '\r')
+	    {
+	      if (__libc_tty_p->t_iflag & IGNCR)
+		continue;
+	      if (__libc_tty_p->t_iflag & ICRNL)
+		ch = '\n';
+	    }
+	  else if ((ch == '\n') && (__libc_tty_p->t_iflag & INLCR))
+	    ch = '\r';
+
+	  /* strip 8th-bit */
+	  if (__libc_tty_p->t_iflag & ISTRIP)
+	    ch &= 0x7f;
+	}
+
+proc_skip:
+      if (__libc_tty_p->t_lflag & ICANON)
+	{
+	  if (__libc_tty_p->t_status & _TS_LNCH)
+	    {
+	      __libc_tty_p->t_status &= ~_TS_LNCH;
+	      __libc_termios_insert_editline (ch);
+	    }
+	  else
+	    {
+	      if (_CC_EQU (VERASE, ch))
+		__libc_termios_erase_editline ();
+	      else if (_CC_EQU (VKILL, ch))
+		__libc_termios_kill_editline ();
+	      else if (ch == '\n' || _CC_EQU (VEOF, ch) || _CC_EQU (VEOL, ch))
+		{
+		  int col = __libc_tty_editline.col;
+		  unsigned char *p = __libc_tty_editline.buf;
+
+		  /* clear column for next access */
+		  __libc_tty_editline.col = 0;
+
+		  /* copy editline into tty queue */
+		  while (--col >= 0)
+		    __libc_termios_put_queue (*p++);
+
+		  /* echo terminate character and put it */
+		  __libc_termios_maybe_echo (ch);
+		  if (_CC_NEQU (VEOF, ch))
+		    __libc_termios_put_queue (ch);
+
+		  return;
+		}
+	      else
+		__libc_termios_insert_editline (ch);
+	    } /* !_TS_LNCH */
+	}
+      else /* !ICANON */
+	{
+	  __libc_termios_maybe_echo (ch);
+	  __libc_tty_p->t_status &= ~_TS_LNCH;
+	  __libc_termios_put_queue (ch);
+	}
+    } /* end of while (1) */
+}
+
+/******************************************************************************/
+/* software signal checker ****************************************************/
+
+void
+__libc_termios_check_signals (void)
+{
+  unsigned char ch;
+
+  if (! __direct_keysense ())
+    return;
+
+  /* software signals */
+  if (__libc_tty_p->t_lflag & ISIG)
+    {
+      ch = __direct_keyinput ();
+      if (! (__libc_tty_p->t_iflag & IGNBRK) && _CC_EQU (VINTR, ch))
+	{
+	  if (__libc_tty_p->t_iflag & BRKINT)
+	    {
+	      __libc_termios_raise_signal (ch, SIGINT);
+	      return;
+	    }
+	}
+      else if (_CC_EQU (VQUIT, ch))
+	{
+	  __libc_termios_raise_signal (ch, SIGQUIT);
+	  return;
+	}
+
+      /* for compatiblity */
+      if (ch == 0x13 && !(__libc_tty_p->t_iflag & IXOFF))
+	{
+	  /* CTRL+S */
+	  while (! __direct_keysense ())
+	    __dpmi_yield ();
+	  ch = __direct_keyinput ();
+	  return;
+	}
+
+      /* push back */
+      __direct_add_keystroke ((int) ch);
+    }
+}
+
+/******************************************************************************/
+
+#endif	/* __DJGPP__ */
