# HG changeset patch
# User Pantxo Diribarne <pantxo.diribarne@gmail.com>
# Date 1542387420 -3600
#      Fri Nov 16 17:57:00 2018 +0100
# Node ID 6886fadf200a12ef7acdb82a1facd4c71d29371d
# Parent  8efea0dcccd4360123253560eeb1396fc589368c
Fix echoed character when "pause" used without argument (bug #55029)

* sysdep.h/cc (octave::kbhit): Add "timeout" argument that defaults to 0.0.
  On Windows use octave::sleep to simulate a timeout. On Unices pass timeout to
  raw_mode. Clear cin error states before trying to read.
  (raw_mode): Add "timeout" argument that defaults to 0.0 and use it to set
  VTIME in termio(s) structure.

* util.cc (octave::sleep): When requested duration if INF, call octave::kbhit
  with a timeout of 0.1s until a character has been typed.

diff -r 8efea0dcccd4 -r 6886fadf200a libinterp/corefcn/sysdep.cc
--- a/libinterp/corefcn/sysdep.cc	Wed Mar 13 01:13:53 2019 -0400
+++ b/libinterp/corefcn/sysdep.cc	Fri Nov 16 17:57:00 2018 +0100
@@ -409,7 +409,7 @@
   //         etc. are NOT disabled.
   // It doesn't matter whether an input \n is mapped to \r, or vice versa.
 
-  void raw_mode (bool on, bool wait)
+  void raw_mode (bool on, bool wait, double timeout)
   {
     static bool curr_on = false;
 
@@ -456,7 +456,7 @@
           s.c_oflag &= ~(ONLRET);
 #endif
           s.c_cc[VMIN] = (wait ? 1 : 0);
-          s.c_cc[VTIME] = 0;
+          s.c_cc[VTIME] = timeout * 10;
         }
       else
         {
@@ -499,6 +499,7 @@
           s.c_oflag &= ~(ONLRET);
 #endif
           s.c_cc[VMIN] = (wait ? 1 : 0);
+          s.c_cc[VTIME] = timeout * 10;
         }
       else
         {
@@ -512,6 +513,7 @@
 #elif defined (HAVE_SGTTY_H)
     {
       octave_unused_parameter (wait);
+      octave_unused_parameter (timeout);
 
       struct sgttyb s;
       static struct sgttyb save_term;
@@ -591,7 +593,7 @@
 
   // Read one character from the terminal.
 
-  int kbhit (bool wait)
+  int kbhit (bool wait, double timeout, bool reset_mode)
   {
 #if defined (HAVE__KBHIT) && defined (HAVE__GETCH)
     // This essentially means we are on a Windows system.
@@ -600,10 +602,15 @@
     if (wait)
       c = _getch ();
     else
-      c = (! _kbhit ()) ? 0 : _getch ();
+      {
+        if (timeout > 0.0)
+          octave::sleep (timeout);
+        
+        c = (! _kbhit ()) ? 0 : _getch ();
+      }
 
 #else
-    raw_mode (true, wait);
+    raw_mode (true, wait, timeout);
 
     // Get current handler.
     octave::interrupt_handler saved_interrupt_handler
@@ -614,15 +621,22 @@
 
     octave::set_interrupt_handler (saved_interrupt_handler, false);
 
+    // Make sure cin is in a readable state
+    std::cin.clear ();
+   
     int c = std::cin.get ();
 
-    if (std::cin.fail () || std::cin.eof ())
-      std::cin.clear ();
+    if (! wait)
+      // Discard eventual additionnal characters
+      std::cin.ignore (std::numeric_limits<int>::max ());
+    
+    std::cin.clear ();
 
     // Restore it, enabling system call restarts (if possible).
     octave::set_interrupt_handler (saved_interrupt_handler, true);
 
-    raw_mode (false, true);
+    if (reset_mode || c >= 0)
+      raw_mode (false, true);
 #endif
 
     return c;
diff -r 8efea0dcccd4 -r 6886fadf200a libinterp/corefcn/sysdep.h
--- a/libinterp/corefcn/sysdep.h	Wed Mar 13 01:13:53 2019 -0400
+++ b/libinterp/corefcn/sysdep.h	Fri Nov 16 17:57:00 2018 +0100
@@ -40,13 +40,15 @@
 
   extern OCTINTERP_API void sysdep_cleanup (void);
 
-  extern OCTINTERP_API void raw_mode (bool, bool wait = true);
+  extern OCTINTERP_API void raw_mode (bool, bool wait = true,
+                                      double timeout = 0.0);
 
   extern OCTINTERP_API FILE * popen (const char *command, const char *mode);
 
   extern OCTINTERP_API int pclose (FILE *f);
 
-  extern OCTINTERP_API int kbhit (bool wait = true);
+  extern OCTINTERP_API int kbhit (bool wait = true, double timeout = 0.0,
+                                  bool reset_on_timeout = true);
 
   extern OCTINTERP_API std::string get_P_tmpdir (void);
 
diff -r 8efea0dcccd4 -r 6886fadf200a libinterp/corefcn/utils.cc
--- a/libinterp/corefcn/utils.cc	Wed Mar 13 01:13:53 2019 -0400
+++ b/libinterp/corefcn/utils.cc	Fri Nov 16 17:57:00 2018 +0100
@@ -1290,18 +1290,14 @@
         int c = -1;
         octave::flush_stdout ();
 
-        struct timespec one_tenth = { 0, 100000000 };
-
         while (c < 0)
           {
-            octave_nanosleep_wrapper (&one_tenth, nullptr);
-
+            c = octave::kbhit (false, 0.1);
+            
             octave_quit ();
-
+            
             if (do_graphics_events)
               gh_manager::process_events ();
-
-            c = octave::kbhit (false);
           }
       }
     else
