# HG changeset patch # User John W. Eaton # Date 1362337361 18000 # Node ID 359d56094efa92663fea91fec4a3938dc5a6ca79 # Parent d200b2b184c125b6120dbbfe388cf4dfa2cb7730 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. diff --git a/libinterp/parse-tree/lex.h b/libinterp/parse-tree/lex.h --- a/libinterp/parse-tree/lex.h +++ b/libinterp/parse-tree/lex.h @@ -153,6 +153,34 @@ std::stack 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; } diff --git a/libinterp/parse-tree/lex.ll b/libinterp/parse-tree/lex.ll --- 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"); }