changeset 16195:b52d2f9294b6

use class for reading lexer input * input.h, input.cc (octave_base_input_reader, octave_terminal_reader, octave_file_reader, octave_eval_string_reader): New classes. (octave_gets): Now a member function of octave_base_reader. (get_user_input): Delete function. Move actions to octave_terminal_reader::get_input and octave_eval_string_reader::get_input. function. Call from octave_file_reader::get_input. Don't check whether reading an eval string. (current_eval_string, get_input_from_eval_string): Delete global variables. (get_debug_input): Check CURR_LEXER->input_from_eval_string instead of global get_input_from_eval_string variable. Don't protect get_input_from_eval_string. * lex.h (octave_lexer::input_reader): New data member. (octave_lexer::octave_lexer (void)): Initialize it. (octave_lexer::octave_lexer (const std::string&), octave_lexer::octave_lexer (FILE *)): New constructors. * lex.h, lex.cc (octave_lexer::input_buffer::fill): New function. (octave_lexer::input_buffer::read): Delete. (octave_lexer::read): Rename from octave_read. Call reader to get input, and then hand it to the input_buffer instead of asking the input buffer to read input. Change all callers. (octave_lexer::input_source, octave_lexer::input_from_eval_string): New functions. Call octave_lexer::input_from_eval_string instead of using get_input_from_eval_string. * oct-parse.in.yy (octave_parser::octave_parser (FILE *), octave_parser::octave_parser (const std::string&)): New constructors. (parse_fcn_file): Pass FILE pointer to octave_parser constructor. (eval_string): Pass string to octave_parser constructor instead of setting global current_eval_string variable.
author John W. Eaton <jwe@octave.org>
date Tue, 05 Mar 2013 10:19:51 -0500
parents b7ca669af528
children 5bcae3970d9d
files libinterp/interpfcn/input.cc libinterp/interpfcn/input.h libinterp/parse-tree/lex.h libinterp/parse-tree/lex.ll libinterp/parse-tree/oct-parse.in.yy libinterp/parse-tree/parse.h
diffstat 6 files changed, 274 insertions(+), 79 deletions(-) [+]
line wrap: on
line diff
--- a/libinterp/interpfcn/input.cc	Tue Mar 05 10:19:47 2013 -0500
+++ b/libinterp/interpfcn/input.cc	Tue Mar 05 10:19:51 2013 -0500
@@ -94,12 +94,6 @@
 // Character to append after successful command-line completion attempts.
 static char Vcompletion_append_char = ' ';
 
-// Global pointer for eval().
-std::string current_eval_string;
-
-// TRUE means get input from current_eval_string.
-bool get_input_from_eval_string = false;
-
 // TRUE means that input is coming from a file that was named on
 // the command line.
 bool input_from_command_line_file = false;
@@ -262,8 +256,8 @@
   return interactive_input (s, eof, force_readline);
 }
 
-static std::string
-octave_gets (bool& eof)
+std::string
+octave_base_reader::octave_gets (bool& eof)
 {
   octave_quit ();
 
@@ -277,7 +271,6 @@
       && (! (reading_fcn_file
              || reading_classdef_file
              || reading_script_file
-             || get_input_from_eval_string
              || input_from_startup_file
              || input_from_command_line_file)))
     {
@@ -341,36 +334,6 @@
   return retval;
 }
 
-// Read a line from the input stream.
-
-std::string
-get_user_input (bool& eof)
-{
-  octave_quit ();
-
-  eof = false;
-
-  std::string retval;
-
-  if (get_input_from_eval_string)
-    {
-      retval = current_eval_string;
-
-      // Clear the global eval string so that the next call will return
-      // an empty character string with EOF = true.
-      current_eval_string = "";
-
-      if (retval.empty ())
-        eof = true;
-    }
-  else
-    retval = octave_gets (eof);
-
-  current_input_line = retval;
-
-  return retval;
-}
-
 // Fix things up so that input can come from file 'name', printing a
 // warning if the file doesn't exist.
 
@@ -642,7 +605,7 @@
       || (reading_fcn_file
           || reading_classdef_file
           || reading_script_file
-          || get_input_from_eval_string
+          || CURR_LEXER->input_from_eval_string ()
           || input_from_startup_file
           || input_from_command_line_file))
     {
@@ -663,9 +626,6 @@
 
       frame.protect_var (input_from_command_line_file);
       input_from_command_line_file = false;
-
-      frame.protect_var (get_input_from_eval_string);
-      get_input_from_eval_string = false;
     }
 
   // octave_parser constructor sets this for us.
@@ -700,6 +660,65 @@
     }
 }
 
+const std::string octave_base_reader::in_src ("invalid");
+
+const std::string octave_terminal_reader::in_src ("terminal");
+
+std::string
+octave_terminal_reader::get_input (bool& eof)
+{
+  octave_quit ();
+
+  eof = false;
+
+  std::string retval = octave_gets (eof);
+
+  current_input_line = retval;
+
+  return retval;
+}
+
+const std::string octave_file_reader::in_src ("file");
+
+std::string
+octave_file_reader::get_input (bool& eof)
+{
+  octave_quit ();
+
+  eof = false;
+
+  std::string retval = octave_fgets (file, eof);
+
+  current_input_line = retval;
+
+  return retval;
+}
+
+const std::string octave_eval_string_reader::in_src ("eval_string");
+
+std::string
+octave_eval_string_reader::get_input (bool& eof)
+{
+  octave_quit ();
+
+  eof = false;
+
+  std::string retval;
+
+  retval = eval_string;
+
+  // Clear the eval string so that the next call will return
+  // an empty character string with EOF = true.
+  eval_string = "";
+
+  if (retval.empty ())
+    eof = true;
+
+  current_input_line = retval;
+
+  return retval;
+}
+
 // If the user simply hits return, this will produce an empty matrix.
 
 static octave_value_list
--- a/libinterp/interpfcn/input.h	Tue Mar 05 10:19:47 2013 -0500
+++ b/libinterp/interpfcn/input.h	Tue Mar 05 10:19:51 2013 -0500
@@ -35,19 +35,11 @@
 
 class octave_value;
 
-extern OCTINTERP_API std::string get_user_input (bool& eof);
-
 extern OCTINTERP_API FILE *get_input_from_file (const std::string& name,
                                                 int warn = 1);
 
 extern OCTINTERP_API FILE *get_input_from_stdin (void);
 
-// Global pointer for eval().
-extern std::string current_eval_string;
-
-// TRUE means get input from current_eval_string.
-extern bool get_input_from_eval_string;
-
 // TRUE means that input is coming from a file that was named on
 // the command line.
 extern bool input_from_command_line_file;
@@ -119,4 +111,139 @@
 
 extern octave_time Vlast_prompt_time;
 
+class
+octave_base_reader
+{
+public:
+
+  friend class octave_input_reader;
+
+  octave_base_reader (void) : count (1) { }
+
+  octave_base_reader (const octave_base_reader&) : count (1) { }
+
+  virtual ~octave_base_reader (void) { }
+
+  virtual std::string get_input (bool& eof) = 0;
+
+  virtual std::string input_source (void) const { return in_src; }
+
+  std::string octave_gets (bool& eof);
+
+private:
+
+  int count;
+
+  static const std::string in_src;
+};
+
+class
+octave_terminal_reader : public octave_base_reader
+{
+public:
+
+  octave_terminal_reader (void) : octave_base_reader () { }
+
+  std::string get_input (bool& eof);
+
+  std::string input_source (void) const { return in_src; }
+
+private:
+
+  static const std::string in_src;
+};
+
+class
+octave_file_reader : public octave_base_reader
+{
+public:
+
+  octave_file_reader (FILE *f_arg)
+    : octave_base_reader (), file (f_arg) { }
+
+  std::string get_input (bool& eof);
+
+  std::string input_source (void) const { return in_src; }
+
+private:
+
+  FILE *file;
+
+  static const std::string in_src;
+};
+
+class
+octave_eval_string_reader : public octave_base_reader
+{
+public:
+
+  octave_eval_string_reader (const std::string& str)
+    : octave_base_reader (), eval_string (str)
+  { }
+
+  std::string get_input (bool& eof);
+
+  std::string input_source (void) const { return in_src; }
+
+private:
+
+  std::string eval_string;
+
+  static const std::string in_src;
+};
+
+class
+octave_input_reader
+{
+public:
+  octave_input_reader (void)
+    : rep (new octave_terminal_reader ())
+  { }
+
+  octave_input_reader (FILE *file)
+    : rep (new octave_file_reader (file))
+  { }
+
+  octave_input_reader (const std::string& str)
+    : rep (new octave_eval_string_reader (str))
+  { }
+
+  octave_input_reader (const octave_input_reader& ir)
+  {
+    rep = ir.rep;
+    rep->count++;
+  }
+
+  octave_input_reader& operator = (const octave_input_reader& ir)
+  {
+    if (&ir != this)
+      {
+        rep = ir.rep;
+        rep->count++;
+      }
+
+    return *this;
+  }
+
+  ~octave_input_reader (void)
+  {
+    if (--rep->count == 0)
+      delete rep;
+  }
+
+  std::string get_input (bool& eof)
+  {
+    return rep->get_input (eof);
+  }
+
+  std::string input_source (void) const
+  {
+    return rep->input_source ();
+  }
+
+private:
+
+  octave_base_reader *rep;
+};
+
 #endif
--- a/libinterp/parse-tree/lex.h	Tue Mar 05 10:19:47 2013 -0500
+++ b/libinterp/parse-tree/lex.h	Tue Mar 05 10:19:51 2013 -0500
@@ -27,6 +27,8 @@
 #include <set>
 #include <stack>
 
+#include "input.h"
+
 extern OCTINTERP_API void cleanup_parser (void);
 
 // Is the given string a keyword?
@@ -317,8 +319,7 @@
       : buffer (), pos (0), chars_left (0), eof (false)
     { }
 
-    // Grab more input from the current input source.
-    void read (void);
+    void fill (const std::string& input, bool eof_arg);
 
     // Copy at most max_size characters to buf.
     int copy_chunk (char *buf, size_t max_size);
@@ -336,7 +337,21 @@
   };
 
   octave_lexer (void)
-    : lexical_feedback (), scanner (0), input_buf ()
+    : lexical_feedback (), scanner (0), input_buf (), input_reader ()
+  {
+    init ();
+  }
+
+  octave_lexer (FILE *file)
+    : lexical_feedback (), scanner (0), input_buf (),
+      input_reader (file)
+  {
+    init ();
+  }
+
+  octave_lexer (const std::string& eval_string)
+    : lexical_feedback (), scanner (0), input_buf (),
+      input_reader (eval_string)
   {
     init ();
   }
@@ -351,7 +366,7 @@
 
   void prep_for_function_file (void);
 
-  int octave_read (char *buf, unsigned int max_size);
+  int read (char *buf, unsigned int max_size);
 
   int handle_end_of_input (void);
 
@@ -448,6 +463,18 @@
   // Object that reads and buffers input.
   input_buffer input_buf;
 
+  octave_input_reader input_reader;
+
+  std::string input_source (void) const
+  {
+    return input_reader.input_source ();
+  }
+
+  bool input_from_eval_string (void) const
+  {
+    return input_source () == "eval_string";
+  }
+
   // For unwind protect.
   static void cleanup (octave_lexer *lexer) { delete lexer; }
 
--- a/libinterp/parse-tree/lex.ll	Tue Mar 05 10:19:47 2013 -0500
+++ b/libinterp/parse-tree/lex.ll	Tue Mar 05 10:19:51 2013 -0500
@@ -118,7 +118,7 @@
 #undef YY_INPUT
 #endif
 #define YY_INPUT(buf, result, max_size) \
-  result = curr_lexer->octave_read (buf, max_size)
+  result = curr_lexer->read (buf, max_size)
 
 // Try to avoid crashing out completely on fatal scanner errors.
 
@@ -1360,11 +1360,12 @@
 }
 
 void
-octave_lexer::input_buffer::read (void)
+octave_lexer::input_buffer::fill (const std::string& input, bool eof_arg)
 {
-  buffer = get_user_input (eof);
+  buffer = input;
   chars_left = buffer.length ();
   pos = buffer.c_str ();
+  eof = eof_arg;
 }
 
 int
@@ -1393,7 +1394,7 @@
         {
           // There isn't enough room to plug the newline character
           // in the buffer so arrange to have it returned on the next
-          // call to octave_read.
+          // call to octave_lexer::read.
           pos = eol;
           chars_left = 1;
         }
@@ -1447,7 +1448,7 @@
       && ! (reading_fcn_file
             || reading_classdef_file
             || reading_script_file
-            || get_input_from_eval_string
+            || input_from_eval_string ()
             || input_from_startup_file))
     yyrestart (stdin, scanner);
 
@@ -1475,12 +1476,16 @@
 }
 
 int
-octave_lexer::octave_read (char *buf, unsigned max_size)
+octave_lexer::read (char *buf, unsigned max_size)
 {
   int status = 0;
 
   if (input_buf.empty ())
-    input_buf.read ();
+    {
+      bool eof = false;
+      std::string input = input_reader.get_input (eof);
+      input_buf.fill (input, eof);
+    }
 
   if (! input_buf.empty ())
     status = input_buf.copy_chunk (buf, max_size);
@@ -1489,7 +1494,7 @@
       status = YY_NULL;
 
       if (! input_buf.at_eof ())
-        fatal_error ("octave_read () in flex scanner failed");
+        fatal_error ("octave_lexer::read () in flex scanner failed");
     }
 
   return status;
--- a/libinterp/parse-tree/oct-parse.in.yy	Tue Mar 05 10:19:47 2013 -0500
+++ b/libinterp/parse-tree/oct-parse.in.yy	Tue Mar 05 10:19:51 2013 -0500
@@ -136,7 +136,7 @@
       if (! parser_symtab_context.empty ()) \
         parser_symtab_context.pop (); \
       if ((interactive || forced_interactive)   \
-          && ! get_input_from_eval_string)      \
+          && ! (curr_lexer)->input_from_eval_string ()) \
         YYACCEPT; \
       else \
         YYABORT; \
@@ -1237,7 +1237,7 @@
                       }
 
                     if (! (reading_fcn_file || reading_script_file
-                           || get_input_from_eval_string))
+                           || (curr_lexer)->input_from_eval_string ()))
                       {
                         curr_parser.bison_error ("function body open at end of input");
                         YYABORT;
@@ -3399,7 +3399,7 @@
       // octave_parser constructor sets this for us.
       frame.protect_var (CURR_LEXER);
 
-      octave_parser curr_parser;
+      octave_parser curr_parser (ffile);
 
       curr_parser.curr_class_name = dispatch_type;
       curr_parser.autoloading = autoload;
@@ -3418,14 +3418,11 @@
         {
           std::string file_type;
 
-          frame.protect_var (get_input_from_eval_string);
           frame.protect_var (reading_fcn_file);
           frame.protect_var (reading_script_file);
           frame.protect_var (reading_classdef_file);
           frame.protect_var (Vecho_executing_commands);
 
-          get_input_from_eval_string = false;
-
           if (! force_script && looking_at_function_keyword (ffile))
             {
               file_type = "function";
@@ -4181,7 +4178,8 @@
 }
 
 octave_value_list
-eval_string (const std::string& s, bool silent, int& parse_status, int nargout)
+eval_string (const std::string& eval_str, bool silent,
+             int& parse_status, int nargout)
 {
   octave_value_list retval;
 
@@ -4190,23 +4188,18 @@
   // octave_parser constructor sets this for us.
   frame.protect_var (CURR_LEXER);
 
-  octave_parser curr_parser;
-
-  frame.protect_var (get_input_from_eval_string);
+  octave_parser curr_parser (eval_str);
+
   frame.protect_var (line_editing);
-  frame.protect_var (current_eval_string);
   frame.protect_var (reading_fcn_file);
   frame.protect_var (reading_script_file);
   frame.protect_var (reading_classdef_file);
 
-  get_input_from_eval_string = true;
   line_editing = false;
   reading_fcn_file = false;
   reading_script_file = false;
   reading_classdef_file = false;
 
-  current_eval_string = s;
-
   do
     {
       curr_parser.reset ();
@@ -4278,11 +4271,11 @@
 }
 
 octave_value
-eval_string (const std::string& s, bool silent, int& parse_status)
+eval_string (const std::string& eval_str, bool silent, int& parse_status)
 {
   octave_value retval;
 
-  octave_value_list tmp = eval_string (s, silent, parse_status, 1);
+  octave_value_list tmp = eval_string (eval_str, silent, parse_status, 1);
 
   if (! tmp.empty ())
     retval = tmp(0);
--- a/libinterp/parse-tree/parse.h	Tue Mar 05 10:19:47 2013 -0500
+++ b/libinterp/parse-tree/parse.h	Tue Mar 05 10:19:51 2013 -0500
@@ -150,6 +150,30 @@
     init ();
   }
 
+  octave_parser (FILE *file)
+    : endfunction_found (false),
+      autoloading (false), fcn_file_from_relative_lookup (false),
+      parsing_subfunctions (false), max_fcn_depth (0),
+      curr_fcn_depth (0), primary_fcn_scope (-1),
+      curr_class_name (), function_scopes (), primary_fcn_ptr (0),
+      stmt_list (0),
+      curr_lexer (new octave_lexer (file)), parser_state (0)
+  {
+    init ();
+  }
+
+  octave_parser (const std::string& eval_string)
+    : endfunction_found (false),
+      autoloading (false), fcn_file_from_relative_lookup (false),
+      parsing_subfunctions (false), max_fcn_depth (0),
+      curr_fcn_depth (0), primary_fcn_scope (-1),
+      curr_class_name (), function_scopes (), primary_fcn_ptr (0),
+      stmt_list (0),
+      curr_lexer (new octave_lexer (eval_string)), parser_state (0)
+  {
+    init ();
+  }
+
   ~octave_parser (void);
 
   void init (void);