Mercurial > hg > octave-nkf
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 +++ b/libinterp/interpfcn/input.cc @@ -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 +++ b/libinterp/interpfcn/input.h @@ -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 +++ b/libinterp/parse-tree/lex.h @@ -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 +++ b/libinterp/parse-tree/lex.ll @@ -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 +++ b/libinterp/parse-tree/oct-parse.in.yy @@ -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 +++ b/libinterp/parse-tree/parse.h @@ -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);