changeset 16183:359d56094efa

handle lexer input buffering with class * lex.h, lex.ll (octave_lexer::input_buffer): New class. (octave_lexer::input_buf): New data member. (octave_lexer::octave_lexer): Initialize it. (octave_lexer::octave_read): Use input_buf to simplify function and replace static data.
author John W. Eaton <jwe@octave.org>
date Sun, 03 Mar 2013 14:02:41 -0500
parents d200b2b184c1
children 05313332d541
files libinterp/parse-tree/lex.h libinterp/parse-tree/lex.ll
diffstat 2 files changed, 81 insertions(+), 50 deletions(-) [+]
line wrap: on
line diff
--- a/libinterp/parse-tree/lex.h
+++ b/libinterp/parse-tree/lex.h
@@ -153,6 +153,34 @@
     std::stack<int> context;
   };
 
+  // Handle buffering of input for lexer.
+
+  class input_buffer
+  {
+  public:
+
+    input_buffer (void)
+      : buffer (), pos (0), chars_left (0), eof (false)
+    { }
+
+    // Grab more input from the current input source.
+    void read (void);
+
+    // Copy at most max_size characters to buf.
+    int copy_chunk (char *buf, size_t max_size);
+
+    bool empty (void) const { return chars_left == 0; }
+
+    bool at_eof (void) const { return eof; }
+
+  private:
+
+    std::string buffer;
+    const char *pos;
+    size_t chars_left;
+    bool eof;
+  };
+
   octave_lexer (void)
     : scanner (0), end_of_input (false), convert_spaces_to_comma (true),
       do_comma_insert (false), at_beginning_of_statement (true),
@@ -169,7 +197,7 @@
       looping (0), defining_func (0), looking_at_function_handle (0),
       block_comment_nesting_level (0),
       looking_at_object_index (), parsed_function_name (),
-      pending_local_variables (), nesting_level ()
+      pending_local_variables (), nesting_level (), input_buf ()
   {
     init ();
   }
@@ -374,6 +402,9 @@
   // a paren?
   bbp_nesting_level nesting_level;
 
+  // Object that reads and buffers input.
+  input_buffer input_buf;
+
   // For unwind protect.
   static void cleanup (octave_lexer *lexer) { delete lexer; }
 
--- a/libinterp/parse-tree/lex.ll
+++ b/libinterp/parse-tree/lex.ll
@@ -1292,6 +1292,49 @@
   char *buf;
 };
 
+void
+octave_lexer::input_buffer::read (void)
+{
+  buffer = get_user_input (eof);
+  chars_left = buffer.length ();
+  pos = buffer.c_str ();
+}
+
+int
+octave_lexer::input_buffer::copy_chunk (char *buf, size_t max_size)
+{
+  static const char * const eol = "\n";
+
+  size_t len = max_size > chars_left ? chars_left : max_size;
+  assert (len > 0);
+
+  memcpy (buf, pos, len);
+
+  chars_left -= len;
+  pos += len;
+
+  // Make sure input ends with a new line character.
+  if (chars_left == 0 && buf[len-1] != '\n')
+    {
+      if (len < max_size)
+        {
+          // There is enough room to plug the newline character in
+          // the buffer.
+          buf[len++] = '\n';
+        }
+      else
+        {
+          // 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.
+          pos = eol;
+          chars_left = 1;
+        }
+    }
+
+  return len;
+}
+
 octave_lexer::~octave_lexer (void)
 {
   // Clear out the stack of token info used to track line and
@@ -1378,61 +1421,18 @@
 int
 octave_lexer::octave_read (char *buf, unsigned max_size)
 {
-  static const char * const eol = "\n";
-  static std::string input_buf;
-  static const char *pos = 0;
-  static size_t chars_left = 0;
-  static bool eof = false;
-
   int status = 0;
 
-  if (chars_left == 0)
-    {
-      pos = 0;
-
-      input_buf = get_user_input (eof);
-
-      chars_left = input_buf.length ();
-
-      pos = input_buf.c_str ();
-    }
-
-  if (chars_left > 0)
-    {
-      size_t len = max_size > chars_left ? chars_left : max_size;
-      assert (len > 0);
-
-      memcpy (buf, pos, len);
-
-      chars_left -= len;
-      pos += len;
-
-      // Make sure input ends with a new line character.
-      if (chars_left == 0 && buf[len-1] != '\n')
-        {
-          if (len < max_size)
-            {
-              // There is enough room to plug the newline character in
-              // the buffer.
-              buf[len++] = '\n';
-            }
-          else
-            {
-              // There isn't enough room to plug the newline character
-              // in the buffer so make sure it is returned on the next
-              // octave_read call.
-              pos = eol;
-              chars_left = 1;
-            }
-        }
-
-      status = len;
-    }
+  if (input_buf.empty ())
+    input_buf.read ();
+
+  if (! input_buf.empty ())
+    status = input_buf.copy_chunk (buf, max_size);
   else
     {
       status = YY_NULL;
 
-      if (! eof)
+      if (! input_buf.at_eof ())
         fatal_error ("octave_read () in flex scanner failed");
     }