changeset 9999:653716f3d976

get_debug_input: force interactive input mode; don't get user input unless stdin is a tty
author John W. Eaton <jwe@octave.org>
date Fri, 18 Dec 2009 03:05:06 -0500
parents 46493feaab7f
children d6e361255a5c
files src/ChangeLog src/input.cc src/input.h src/octave.cc
diffstat 4 files changed, 97 insertions(+), 33 deletions(-) [+]
line wrap: on
line diff
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,13 @@
+2009-12-18  John W. Eaton  <jwe@octave.org>
+
+	* input.cc (get_debug_input): Don't attempt to get user input
+	unless stdin is a tty.  Force interactive input mode when
+	reading debugging input.
+	(octave_gets): Bypass readline if get_input_from_eval_string is true.
+
+	* input.cc, input.h (stdin_is_tty): New variable.
+	* octave.cc (octave_main): Set it to true if stdin is not a tty.
+
 2009-12-16  Jaroslav Hajek  <highegg@gmail.com>
 
 	* DLD-FUNCTIONS/max.cc (do_minmax_red_op<boolNDArray>): New
--- a/src/input.cc
+++ b/src/input.cc
@@ -55,6 +55,7 @@
 #include "gripes.h"
 #include "help.h"
 #include "input.h"
+#include "lex.h"
 #include "load-path.h"
 #include "oct-map.h"
 #include "oct-hist.h"
@@ -112,6 +113,9 @@
 // the command line.
 bool input_from_command_line_file = false;
 
+// TRUE means that stdin is a terminal, not a pipe or redirected file.
+bool stdin_is_tty = false;
+
 // TRUE means we're parsing a function file.
 bool reading_fcn_file = false;
 
@@ -264,6 +268,7 @@
       && (! (reading_fcn_file
 	     || reading_classdef_file
 	     || reading_script_file
+	     || get_input_from_eval_string
 	     || input_from_startup_file
 	     || input_from_command_line_file)))
     {
@@ -686,49 +691,92 @@
   unwind_protect::protect_var (VPS1);
   VPS1 = prompt;
 
-  while (Vdebugging)
+  if (stdin_is_tty)
     {
-      reset_error_handler ();
+      if (! (interactive || forced_interactive)
+          || (reading_fcn_file
+              || reading_classdef_file
+              || reading_script_file
+              || get_input_from_eval_string
+              || input_from_startup_file
+              || input_from_command_line_file))
+        {
+          unwind_protect::protect_var (forced_interactive);
+          forced_interactive = true;
 
-      reset_parser ();
+          unwind_protect::protect_var (reading_fcn_file);
+          reading_fcn_file = false;
 
-      // Save current value of global_command.
-      unwind_protect::protect_var (global_command);
+          unwind_protect::protect_var (reading_classdef_file);
+          reading_classdef_file = false;
 
-      // Do this with an unwind-protect cleanup function so that the
-      // forced variables will be unmarked in the event of an interrupt.
-      symbol_table::scope_id scope = symbol_table::top_scope ();
-      unwind_protect::add_fcn (symbol_table::unmark_forced_variables, scope);
+          unwind_protect::protect_var (reading_script_file);
+          reading_script_file = false;
+
+          unwind_protect::protect_var (input_from_startup_file);
+          input_from_startup_file = false;
+
+          unwind_protect::protect_var (input_from_command_line_file);
+          input_from_command_line_file = false;
 
-      // This is the same as yyparse in parse.y.
-      int retval = octave_parse ();
+          unwind_protect::protect_var (get_input_from_eval_string);
+          get_input_from_eval_string = false;
+
+          YY_BUFFER_STATE old_buf = current_buffer ();
+          YY_BUFFER_STATE new_buf = create_buffer (get_input_from_stdin ());
 
-      if (retval == 0 && global_command)
-	{
-	  global_command->accept (*current_evaluator);
+          unwind_protect::add_fcn (switch_to_buffer, old_buf);
+          unwind_protect::add_fcn (delete_buffer, new_buf);
+
+          switch_to_buffer (new_buf);
+        }
 
-	  // FIXME -- To avoid a memory leak, global_command should be
-	  // deleted, I think.  But doing that here causes trouble if
-	  // an error occurs while executing a debugging command
-	  // (dbstep, for example). It's not clear to me why that
-	  // happens.
-	  //
-	  // delete global_command;
-	  //
-	  // global_command = 0;
+      while (Vdebugging)
+        {
+          reset_error_handler ();
+
+          reset_parser ();
+
+          // Save current value of global_command.
+          unwind_protect::protect_var (global_command);
+
+          // Do this with an unwind-protect cleanup function so that the
+          // forced variables will be unmarked in the event of an interrupt.
+          symbol_table::scope_id scope = symbol_table::top_scope ();
+          unwind_protect::add_fcn (symbol_table::unmark_forced_variables, scope);
+
+          // This is the same as yyparse in parse.y.
+          int retval = octave_parse ();
+
+          if (retval == 0 && global_command)
+            {
+              global_command->accept (*current_evaluator);
 
-	  if (octave_completion_matches_called)
-	    octave_completion_matches_called = false;
-	}
+              // FIXME -- To avoid a memory leak, global_command should be
+              // deleted, I think.  But doing that here causes trouble if
+              // an error occurs while executing a debugging command
+              // (dbstep, for example). It's not clear to me why that
+              // happens.
+              //
+              // delete global_command;
+              //
+              // global_command = 0;
 
-      // Unmark forced variables.
-      unwind_protect::run ();
+              if (octave_completion_matches_called)
+                octave_completion_matches_called = false;
+            }
+
+          // Unmark forced variables.
+          unwind_protect::run ();
 
-      // Restore previous value of global_command.
-      unwind_protect::run ();
+          // Restore previous value of global_command.
+          unwind_protect::run ();
 
-      OCTAVE_QUIT;
+          OCTAVE_QUIT;
+        }
     }
+  else
+    warning ("invalid attempt to debug script read from stdin");
 
   unwind_protect::run_frame (uwp_frame);
 }
--- a/src/input.h
+++ b/src/input.h
@@ -54,6 +54,9 @@
 // the command line.
 extern bool input_from_command_line_file;
 
+// TRUE means that stdin is a terminal, not a pipe or redirected file.
+extern bool stdin_is_tty;
+
 // TRUE means we're parsing a function file.
 extern bool reading_fcn_file;
 
--- a/src/octave.cc
+++ b/src/octave.cc
@@ -784,8 +784,11 @@
   // Is input coming from a terminal?  If so, we are probably
   // interactive.
 
-  interactive = (! embedded
-		 && isatty (fileno (stdin)) && isatty (fileno (stdout)));
+  // If stdin is not a tty, then we are reading commands from a pipe or
+  // a redirected file.
+  stdin_is_tty = isatty (fileno (stdin));
+
+  interactive = (! embedded && stdin_is_tty && isatty (fileno (stdout)));
 
   if (! interactive && ! forced_line_editing)
     line_editing = false;