28#if defined (HAVE_CONFIG_H)
52#include "builtin-defun-decls.h"
115 std::string line = command_editor::get_line_buffer ();
117 int pos = line.length () - text.length ();
123 while (pos >= 0 && (line[pos] ==
')' || line[pos] ==
'}'))
125 if (line[pos] ==
')')
130 while (curly_count + paren_count > 0 && --pos >= 0)
132 if (line[pos] ==
')')
134 else if (line[pos] ==
'(')
136 else if (line[pos] ==
'}')
138 else if (line[pos] ==
'{')
142 while (--pos >= 0 && line[pos] ==
' ')
146 while (pos >= 0 && (isalnum (line[pos]) || line[pos] ==
'_'))
150 return (line.substr (pos, last + 1 - pos));
152 return std::string ();
157 std::string& prefix, std::string& hint)
161 std::size_t pos = text.rfind (
'.');
164 if (pos != std::string::npos)
166 if (pos == text.length ())
169 hint = text.substr (pos+1);
171 prefix = text.substr (0, pos);
179 std::string base_name = prefix;
181 pos = base_name.find_first_of (
"{(. ");
183 if (pos != std::string::npos)
184 base_name = base_name.substr (0, pos);
195 unwind_protect frame;
232 bool retval = (! text.empty ()
233 && (text !=
"." || prev_char ==
')' || prev_char ==
'}')
235 && text.find (
"..") == std::string::npos
236 && text.rfind (
'.') != std::string::npos);
245 std::string& hint,
bool& deemed_struct)
251 char prev_char = command_editor::get_prev_char (text.length ());
269 static std::string dirfns_commands[] = {
"cd",
"isfile",
"isfolder",
"ls"};
270 static const std::size_t dirfns_commands_length = 4;
274 std::string line = command_editor::get_line_buffer ();
276 for (std::size_t i = 0; i < dirfns_commands_length; i++)
278 int index = line.find (dirfns_commands[i] +
' ');
295 static std::string prefix;
296 static std::string hint;
298 static std::size_t hint_len = 0;
300 static int list_index = 0;
301 static int name_list_len = 0;
302 static int name_list_total_len = 0;
306 static int matches = 0;
319 bool deemed_struct =
false;
327 name_list_len = name_list.
numel ();
334 file_name_list = command_editor::generate_filename_completions (text);
336 name_list.
append (file_name_list);
340 name_list_total_len = name_list.
numel ();
342 hint_len = hint.length ();
346 for (
int i = 0; i < name_list_len; i++)
347 if (hint == name_list[i].substr (0, hint_len))
351 if (name_list_total_len > 0 && matches > 0)
353 while (list_index < name_list_total_len)
355 std::string
name = name_list[list_index];
359 if (hint ==
name.substr (0, hint_len))
363 if (list_index <= name_list_len && ! prefix.empty ())
364 retval = (prefix ==
"." ?
"" : prefix) +
'.' +
name;
369 command_editor::get_prev_char (text.length ());
376 command_editor::set_completion_append_character (
'\0');
383 command_editor::set_completion_append_character
412 : m_interpreter (interp), m_PS1 (R
"(octave:\#> )"), m_PS2 ("> "),
413 m_completion_append_char (
' '), m_gud_mode (false),
414 m_mfile_encoding (
"utf-8"), m_auto_repeat_debug_command (true),
415 m_last_debugging_command (
"\n"), m_input_event_hook_functions (),
416 m_initialized (false)
427 command_editor::force_default_editor ();
434 command_editor::set_name (
"Octave");
439 static const char *s =
"\t\n !\"\'*+-/:;<=>(){}[\\]^`~";
441 command_editor::set_basic_word_break_characters (s);
443 command_editor::set_completer_word_break_characters (s);
445 command_editor::set_basic_quote_characters (R
"(")");
447 command_editor::set_filename_quote_characters (" \t\n\\\"'@<>=;|&()#$`?*[!:{");
449 command_editor::set_completer_quote_characters (R
"('")");
477 "completion_append_char");
499 "__mfile_encoding__");
522 if (codec ==
reinterpret_cast<void *
> (-1))
526 error (
"__mfile_encoding__: conversion from encoding '%s' "
527 "not supported", encoding.c_str ());
529 error (
"__mfile_encoding__: error %d opening encoding '%s'",
530 errno, encoding.c_str ());
539 feval (
"__event_manager_gui_preference__",
546 static std::string load_path_dir (
const std::string& dir)
548 std::string lp_dir = dir;
552 if (ipos != std::string::npos)
553 lp_dir = lp_dir.erase (ipos+1);
557 if (ipos != std::string::npos
558 && lp_dir.substr (ipos+1).compare (
"private") == 0)
560 lp_dir = lp_dir.erase (ipos);
565 if (ipos != std::string::npos && lp_dir[ipos+1] ==
'@')
567 lp_dir = lp_dir.erase (ipos);
572 while (ipos != std::string::npos && lp_dir[ipos+1] ==
'+')
574 lp_dir = lp_dir.erase (ipos);
587 enc = enc_it->second;
596 std::transform (enc.begin (), enc.end (), enc.begin (), ::tolower);
598 if (enc.compare (
"delete") == 0)
604 else if (enc.compare (
"utf-8"))
613 if (codec ==
reinterpret_cast<void *
> (-1))
616 error (
"dir_encoding: conversion from encoding '%s' "
617 "not supported", enc.c_str ());
619 error (
"dir_encoding: error %d opening encoding '%s'.",
620 errno, enc.c_str ());
636 "auto_repeat_debug_command");
641 std::string prompt_string = prompt +
"(yes or no) ";
649 if (input_buf ==
"yes")
651 else if (input_buf ==
"no")
654 message (
nullptr,
"Please answer yes or no.");
698 std::string prompt = args(0).xstring_value (
"input: unrecognized argument");
700 bool read_as_string =
false;
704 = args(1).xstring_value (
"input: second argument must be 's'.");
705 if (literal.length () != 1 || literal[0] !=
's')
706 error (
"input: second argument must be 's'.");
708 read_as_string =
true;
721 if (input_buf.empty ())
722 error (
"input: reading user-input failed!");
724 std::size_t
len = input_buf.length ();
728 if (input_buf[
len - 1] !=
'\n')
734 if (input_buf.length () == 1 && input_buf[0] ==
'\n')
737 retval(0) = input_buf;
741 int parse_status = 0;
767 hook_function_list::iterator p
794 std::string retval = command_editor::readline (s, eof);
796 if (! eof && retval.empty ())
827 bool history_skip_auto_repeated_debugging_command =
false;
844 && retval.find_first_not_of (
" \t\n\r") != std::string::npos)
858 history_skip_auto_repeated_debugging_command =
true;
863 if (! history_skip_auto_repeated_debugging_command)
865 if (command_history::add (retval))
871 if (! retval.empty () && retval.back () !=
'\n')
892 :
base_reader (interp), m_eof (false), m_input_queue ()
895 std::string get_input (
const std::string& prompt,
bool& eof);
897 std::string input_source (
void)
const {
return s_in_src; }
899 bool input_from_terminal (
void)
const {
return true; }
904 std::queue<std::string> m_input_queue;
906 static const std::string s_in_src;
921 file_reader (
interpreter& interp, FILE *f_arg,
const std::string& enc)
922 :
base_reader (interp), m_file (f_arg), m_encoding (enc) { }
924 std::string get_input (
const std::string& prompt,
bool& eof);
926 std::string input_source (
void)
const {
return s_in_src; }
928 bool input_from_file (
void)
const {
return true; }
934 std::string m_encoding;
936 static const std::string s_in_src;
944 eval_string_reader (
interpreter& interp,
const std::string& str)
948 std::string get_input (
const std::string& prompt,
bool& eof);
950 std::string input_source (
void)
const {
return s_in_src; }
952 bool input_from_eval_string (
void)
const {
return true; }
956 std::string m_eval_string;
958 static const std::string s_in_src;
962 : m_rep (new terminal_reader (interp))
966 : m_rep (new file_reader (interp, file))
970 : m_rep (new file_reader (interp, file, enc))
974 : m_rep (new eval_string_reader (interp, str))
979 const std::string terminal_reader::s_in_src (
"terminal");
989 terminal_reader::get_input (
const std::string& prompt,
bool& eof)
995 if (m_input_queue.empty ())
997 std::string
input = octave_gets (prompt, m_eof);
1018 std::size_t beg = 0;
1021 std::size_t end =
input.find (
'\n', beg);
1023 if (end == std::string::npos)
1025 m_input_queue.push (
input.substr (beg));
1030 m_input_queue.push (
input.substr (beg, end-beg+1));
1036 std::string retval = m_input_queue.front ();
1037 m_input_queue.pop ();
1039 if (m_input_queue.empty ())
1045 const std::string file_reader::s_in_src (
"file");
1048 file_reader::get_input (
const std::string& ,
bool& eof)
1054 std::string src_str =
fgets (m_file, eof);
1056 std::string mfile_encoding;
1058 if (m_encoding.empty ())
1060 input_system& input_sys = m_interpreter.get_input_system ();
1064 mfile_encoding = m_encoding;
1066 std::string encoding;
1067 if (mfile_encoding.compare (
"system") == 0)
1071 std::transform (encoding.begin (), encoding.end (), encoding.begin (),
1075 encoding = mfile_encoding;
1077 if (encoding.compare (
"utf-8") == 0)
1080 if (src_str.compare (0, 3,
"\xef\xbb\xbf") == 0)
1081 src_str.erase (0, 3);
1087 "Invalid UTF-8 byte sequences have been replaced.");
1092 const char *src = src_str.c_str ();
1093 std::size_t srclen = src_str.length ();
1102 error (
"file_reader::get_input: "
1103 "converting from codepage '%s' to UTF-8: %s",
1104 encoding.c_str (), std::strerror (errno));
1106 unwind_action free_utf8_str ([=] () {
::free (utf8_str); });
1108 src_str = std::string (
reinterpret_cast<char *
> (utf8_str), length);
1114 const std::string eval_string_reader::s_in_src (
"eval_string");
1117 eval_string_reader::get_input (
const std::string& ,
bool& eof)
1125 retval = m_eval_string;
1131 if (retval.empty ())
1176 int nargin = args.
length ();
1178 if (nargin < 1 || nargin > 2)
1200 int nargin = args.
length ();
1210 prompt = args(0).xstring_value (
"yes_or_no: PROMPT must be a string");
1233 int nargin = args.
length ();
1243 = args(0).xstring_value (
"keyboard: PROMPT must be a string");
1253DEFUN (completion_matches, args, nargout,
1269 std::string hint = args(0).string_value ();
1300 if (! list.empty ())
1311 int len = list.numel ();
1313 for (
int i = 0; i <
len; i++)
1337DEFUN (readline_read_init_file, args, ,
1350 int nargin = args.
length ();
1356 command_editor::read_init_file ();
1359 std::string file = args(0).string_value ();
1361 command_editor::read_init_file (file);
1367DEFUN (readline_re_read_init_file, args, ,
1380 command_editor::re_read_init_file ();
1385DEFMETHOD (add_input_event_hook, interp, args, ,
1405 int nargin = args.
length ();
1407 if (nargin < 1 || nargin > 2)
1413 user_data = args(1);
1417 hook_function hook_fcn (args(0), user_data);
1421 return ovl (hook_fcn.id ());
1424DEFMETHOD (remove_input_event_hook, interp, args, ,
1434 int nargin = args.
length ();
1436 if (nargin < 1 || nargin > 2)
1439 std::string hook_fcn_id = args(0).xstring_value (
"remove_input_event_hook: argument not valid as a hook function name or id");
1441 bool warn = (nargin < 2);
1446 warning (
"remove_input_event_hook: %s not found in list",
1447 hook_fcn_id.c_str ());
1493 return input_sys.
PS1 (args, nargout);
1517 return input_sys.
PS2 (args, nargout);
1520DEFMETHOD (completion_append_char, interp, args, nargout,
1540DEFMETHOD (__request_drawnow__, , args, ,
1547 int nargin = args.
length ();
1560DEFMETHOD (__gud_mode__, interp, args, nargout,
1568 return input_sys.
gud_mode (args, nargout);
1571DEFMETHOD (__mfile_encoding__, interp, args, nargout,
1582DEFMETHOD (dir_encoding, interp, args, nargout,
1622 int nargin = args.
length ();
1624 if (nargin < 1 || nargin > 2)
1628 = args(0).xstring_value (
"dir_encoding: DIR must be a string");
1639 std::string encoding
1640 = args(1).xstring_value (
"dir_encoding: ENCODING must be a string");
1645 return ovl (retval);
1649DEFMETHOD (auto_repeat_debug_command, interp, args, nargout,
charNDArray max(char d, const charNDArray &m)
std::string octave_gets(const std::string &prompt, bool &eof)
static const std::string s_in_src
interpreter & m_interpreter
void set_discard_warning_messages(bool flag)
OCTINTERP_API octave_value discard_warning_messages(const octave_value_list &args, int nargout)
Provides threadsafe access to octave.
void append_history(const std::string &hist_entry)
OCTINTERP_API void set_workspace(void)
void post_input_event(void)
void exit_debugger_event(void)
void pre_input_event(void)
error_system & get_error_system(void)
load_path & get_load_path(void)
tree_evaluator & get_evaluator(void)
octave_value_list eval_string(const std::string &eval_str, bool silent, int &parse_status, int nargout)
void handle_exception(const execution_exception &ee)
event_manager & get_event_manager(void)
bool is_variable(const std::string &name) const
output_system & get_output_system(void)
input_system & get_input_system(void)
bool interactive(void) const
void recover_from_exception(void)
OCTAVE_API void stamp(void)
octave_idx_type length(void) const
bool is_classdef_object(void) const
bool is_defined(void) const
bool isstruct(void) const
string_vector map_keys(void) const
string_vector & append(const std::string &s)
string_vector & sort(bool make_uniq=false)
octave_idx_type numel(void) const
void keyboard(const std::string &prompt="keyboard> ")
bool in_debug_repl(void) const
OCTINTERP_API void print_usage(void)
#define DEFMETHOD(name, interp_name, args_name, nargout_name, doc)
Macro to define a builtin method.
#define DEFUN(name, args_name, nargout_name, doc)
Macro to define a builtin function.
void warning(const char *fmt,...)
void warning_with_id(const char *id, const char *fmt,...)
void error(const char *fmt,...)
void message(const char *name, const char *fmt,...)
OCTAVE_EXPORT octave_value_list Fdrawnow(octave::interpreter &interp, const octave_value_list &args, int)
ColumnVector transform(const Matrix &m, double x, double y, double z)
string_vector make_name_list(void)
void * octave_iconv_open_wrapper(const char *tocode, const char *fromcode)
int octave_iconv_close_wrapper(void *cd)
const char * octave_locale_charset_wrapper(void)
OCTAVE_API unsigned int u8_validate(const std::string &who, std::string &in_string, const u8_fallback_type type=U8_REPLACEMENT_CHAR)
std::string fgets(FILE *f)
static uint32_t state[624]
input_system & __get_input_system__(const std::string &who)
interpreter & __get_interpreter__(const std::string &who)
octave_value_list feval(const char *name, const octave_value_list &args, int nargout)
Evaluate an Octave function (built-in or interpreted) and return the list of result values.
static int input(yyscan_t yyscanner)
octave_value_list ovl(const OV_Args &... args)
Construct an octave_value_list with less typing.
static OCTAVE_NORETURN void eval_error(const char *msg, const dim_vector &x, const dim_vector &y)
static std::string dir_sep_chars
OCTAVE_NAMESPACE_BEGIN int pipe_handler_error_count
uint8_t * octave_u8_conv_from_encoding(const char *fromcode, const char *src, size_t srclen, size_t *lengthp)
octave_value set_internal_variable(bool &var, const octave_value_list &args, int nargout, const char *nm)