# HG changeset patch
# User Pantxo Diribarne <pantxo.diribarne@gmail.com>
# Date 1542387420 -3600
#      Fri Nov 16 17:57:00 2018 +0100
# Branch stable
# Node ID d6f4f41ad2f3f59b66b6ab7c41bbc1fc75ae8370
# Parent  50439c2e8bbfe2ee9662fc465b6656642e6a1fb5
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.
  (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 50439c2e8bbf -r d6f4f41ad2f3 libinterp/corefcn/sysdep.cc
--- a/libinterp/corefcn/sysdep.cc	Wed Jan 16 20:32:15 2019 -0800
+++ b/libinterp/corefcn/sysdep.cc	Fri Nov 16 17:57:00 2018 +0100
@@ -358,7 +358,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;
 
@@ -405,7 +405,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
         {
@@ -448,6 +448,7 @@
           s.c_oflag &= ~(ONLRET);
 #endif
           s.c_cc[VMIN] = (wait ? 1 : 0);
+          s.c_cc[VTIME] = timeout * 10;
         }
       else
         {
@@ -461,6 +462,7 @@
 #elif defined (HAVE_SGTTY_H)
     {
       octave_unused_parameter (wait);
+      octave_unused_parameter (timeout);
 
       struct sgttyb s;
       static struct sgttyb save_term;
@@ -540,7 +542,7 @@
 
   // Read one character from the terminal.
 
-  int kbhit (bool wait)
+  int kbhit (bool wait, double timeout)
   {
 #if defined (HAVE__KBHIT) && defined (HAVE__GETCH)
     // This essentially means we are on a Windows system.
@@ -549,10 +551,16 @@
     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
@@ -562,11 +570,22 @@
     // read can be interrupted.
 
     octave::set_interrupt_handler (saved_interrupt_handler, false);
-
+    
+    if (std::cin.fail () || std::cin.eof ())
+      {
+        std::cin.seekg (0, std::ios::cur);
+        std::cin.clear ();
+      }
+   
     int c = std::cin.get ();
 
-    if (std::cin.fail () || std::cin.eof ())
-      std::cin.clear ();
+    if (! wait)
+      // Discard any additionnal characters
+      std::cin.ignore (std::numeric_limits<std::streamsize>::max ());
+    
+    std::cin.seekg (0, std::ios::cur);
+    std::cin.clear ();
+    
 
     // Restore it, enabling system call restarts (if possible).
     octave::set_interrupt_handler (saved_interrupt_handler, true);
diff -r 50439c2e8bbf -r d6f4f41ad2f3 libinterp/corefcn/sysdep.h
--- a/libinterp/corefcn/sysdep.h	Wed Jan 16 20:32:15 2019 -0800
+++ b/libinterp/corefcn/sysdep.h	Fri Nov 16 17:57:00 2018 +0100
@@ -40,13 +40,14 @@
 
   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);
 
   extern OCTINTERP_API std::string get_P_tmpdir (void);
 
diff -r 50439c2e8bbf -r d6f4f41ad2f3 libinterp/corefcn/utils.cc
--- a/libinterp/corefcn/utils.cc	Wed Jan 16 20:32:15 2019 -0800
+++ 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
