28 #if defined (HAVE_CONFIG_H)
95 quoting_filename (
const std::string&
text,
int,
char quote)
108 find_indexed_expression (
const std::string&
text)
112 int pos =
line.length () -
text.length ();
118 while (pos >= 0 && (
line[pos] ==
')' ||
line[pos] ==
'}'))
120 if (
line[pos] ==
')')
125 while (curly_count + paren_count > 0 && --pos >= 0)
127 if (
line[pos] ==
')')
129 else if (
line[pos] ==
'(')
131 else if (
line[pos] ==
'}')
133 else if (
line[pos] ==
'{')
137 while (--pos >= 0 &&
line[pos] ==
' ')
141 while (pos >= 0 && (isalnum (
line[pos]) ||
line[pos] ==
'_'))
145 return (
line.substr (pos, last + 1 - pos));
147 return std::string ();
151 generate_struct_completions (
const std::string&
text,
152 std::string& prefix, std::string& hint)
156 std::size_t pos =
text.rfind (
'.');
159 if (pos != std::string::npos)
161 if (pos ==
text.length ())
164 hint =
text.substr (pos+1);
166 prefix =
text.substr (0, pos);
171 prefix = find_indexed_expression (
text);
174 std::string base_name = prefix;
176 pos = base_name.find_first_of (
"{(. ");
178 if (pos != std::string::npos)
179 base_name = base_name.substr (0, pos);
224 looks_like_struct (
const std::string&
text,
char prev_char)
226 bool retval = (!
text.empty ()
227 && (
text !=
"." || prev_char ==
')' || prev_char ==
'}')
229 &&
text.find (
"..") == std::string::npos
230 &&
text.rfind (
'.') != std::string::npos);
238 generate_possible_completions (
const std::string&
text, std::string& prefix,
239 std::string& hint,
bool& deemed_struct)
246 deemed_struct = looks_like_struct (
text, prev_char);
249 names = generate_struct_completions (
text, prefix, hint);
261 is_completing_dirfns ()
263 static std::string dirfns_commands[] = {
"cd",
"isfile",
"isfolder",
"ls"};
264 static const std::size_t dirfns_commands_length = 4;
270 for (std::size_t i = 0; i < dirfns_commands_length; i++)
272 int index =
line.find (dirfns_commands[i] +
' ');
285 generate_completion (
const std::string&
text,
int state)
289 static std::string prefix;
290 static std::string hint;
292 static std::size_t hint_len = 0;
294 static int list_index = 0;
295 static int name_list_len = 0;
296 static int name_list_total_len = 0;
300 static int matches = 0;
313 bool deemed_struct =
false;
315 if (is_completing_dirfns ())
318 name_list = generate_possible_completions (
text, prefix, hint,
321 name_list_len = name_list.
numel ();
330 name_list.
append (file_name_list);
334 name_list_total_len = name_list.
numel ();
336 hint_len = hint.length ();
340 for (
int i = 0; i < name_list_len; i++)
341 if (hint == name_list[i].substr (0, hint_len))
345 if (name_list_total_len > 0 && matches > 0)
347 while (list_index < name_list_total_len)
349 std::string name = name_list[list_index];
353 if (hint == name.substr (0, hint_len))
357 if (list_index <= name_list_len && ! prefix.empty ())
358 retval = (prefix ==
"." ?
"" : prefix) +
'.' + name;
365 if (matches == 1 && looks_like_struct (retval, prev_char))
389 internal_input_event_hook_fcn ()
405 : m_interpreter (interp), m_PS1 (R
"(octave:\#> )"), m_PS2 ("> "),
406 m_completion_append_char (
' '), m_gud_mode (false),
407 m_mfile_encoding (
"utf-8"), m_auto_repeat_debug_command (true),
408 m_last_debugging_command (
"\n"), m_input_event_hook_functions (),
409 m_initialized (false)
433 static const char *s =
"\t\n !\"\'*+-/:;<=>(){}[\\]^`~";
451 m_initialized = true;
471 "completion_append_char");
486 std::string saved_encoding = m_mfile_encoding;
497 if (m_mfile_encoding != saved_encoding)
499 if (m_mfile_encoding.empty ())
501 m_mfile_encoding =
"system";
506 m_mfile_encoding.end (),
507 m_mfile_encoding.begin (), ::tolower);
509 std::string encoding = (m_mfile_encoding.compare (
"system") == 0)
516 if (codec ==
reinterpret_cast<void *
> (-1))
518 m_mfile_encoding = saved_encoding;
520 error (
"mfile_encoding: conversion from encoding '%s' "
521 "not supported", encoding.c_str ());
523 error (
"mfile_encoding: error %d opening encoding '%s'",
524 errno, encoding.c_str ());
540 load_path_dir (
const std::string& dir)
542 std::string lp_dir = dir;
546 if (ipos != std::string::npos)
547 lp_dir = lp_dir.erase (ipos+1);
551 if (ipos != std::string::npos
552 && lp_dir.substr (ipos+1).compare (
"private") == 0)
554 lp_dir = lp_dir.erase (ipos);
559 if (ipos != std::string::npos && lp_dir[ipos+1] ==
'@')
561 lp_dir = lp_dir.erase (ipos);
566 while (ipos != std::string::npos && lp_dir[ipos+1] ==
'+')
568 lp_dir = lp_dir.erase (ipos);
578 std::string enc = m_mfile_encoding;
582 auto enc_it = m_dir_encoding.find (key);
583 if (enc_it != m_dir_encoding.end ())
584 enc = enc_it->second;
594 std::transform (enc.begin (), enc.end (), enc.begin (), ::tolower);
596 if (enc.compare (
"delete") == 0)
599 m_dir_encoding.erase (load_path_dir (dir));
602 else if (enc.compare (
"utf-8"))
611 if (codec ==
reinterpret_cast<void *
> (-1))
614 error (
"dir_encoding: conversion from encoding '%s' "
615 "not supported", enc.c_str ());
617 error (
"dir_encoding: error %d opening encoding '%s'.",
618 errno, enc.c_str ());
624 m_dir_encoding[load_path_dir (dir)] = enc;
634 "auto_repeat_debug_command");
640 std::string prompt_string = prompt +
"(yes or no) ";
648 if (input_buf ==
"yes")
650 else if (input_buf ==
"no")
653 message (
nullptr,
"Please answer yes or no.");
664 bool eval_error =
false;
688 return gnu_readline (s, eof);
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;
744 = m_interpreter.
eval_string (input_buf,
true, parse_status, nargout);
758 return ! m_input_event_hook_functions.
empty ();
764 m_input_event_hook_functions.
insert (hook_fcn.
id (), hook_fcn);
771 = m_input_event_hook_functions.
find (hook_fcn_id);
773 if (p == m_input_event_hook_functions.
end ())
776 m_input_event_hook_functions.
erase (p);
783 m_input_event_hook_functions.
clear ();
789 m_input_event_hook_functions.
run ();
793 input_system::gnu_readline (
const std::string& s,
bool& eof)
const
801 if (! eof && retval.empty ())
833 bool history_skip_auto_repeated_debugging_command =
false;
850 && retval.find_first_not_of (
" \t\n\r") != std::string::npos)
864 history_skip_auto_repeated_debugging_command =
true;
869 if (! history_skip_auto_repeated_debugging_command)
877 if (! retval.empty () && retval.back () !=
'\n')
898 :
base_reader (interp), m_eof (false), m_input_queue ()
901 std::string get_input (
const std::string& prompt,
bool& eof);
903 std::string input_source ()
const {
return s_in_src; }
905 bool input_from_terminal ()
const {
return true; }
910 std::queue<std::string> m_input_queue;
912 static const std::string s_in_src;
927 file_reader (
interpreter& interp, FILE *f_arg,
const std::string& enc)
928 :
base_reader (interp), m_file (f_arg), m_encoding (enc) { }
930 std::string get_input (
const std::string& prompt,
bool& eof);
932 std::string input_source ()
const {
return s_in_src; }
934 bool input_from_file ()
const {
return true; }
940 std::string m_encoding;
942 static const std::string s_in_src;
950 eval_string_reader (
interpreter& interp,
const std::string& str)
954 std::string get_input (
const std::string& prompt,
bool& eof);
956 std::string input_source ()
const {
return s_in_src; }
958 bool input_from_eval_string ()
const {
return true; }
962 std::string m_eval_string;
964 static const std::string s_in_src;
968 : m_rep (new terminal_reader (interp))
972 : m_rep (new file_reader (interp, file))
976 const std::string& enc)
977 : m_rep (new file_reader (interp, file, enc))
981 : m_rep (new eval_string_reader (interp, str))
984 const std::string base_reader::s_in_src (
"invalid");
986 const std::string terminal_reader::s_in_src (
"terminal");
996 terminal_reader::get_input (
const std::string& prompt,
bool& eof)
1002 if (m_input_queue.empty ())
1004 std::string input = octave_gets (prompt, m_eof);
1006 std::size_t
len = input.size ();
1025 std::size_t beg = 0;
1028 std::size_t end = input.find (
'\n', beg);
1030 if (end == std::string::npos)
1032 m_input_queue.push (input.substr (beg));
1037 m_input_queue.push (input.substr (beg, end-beg+1));
1043 std::string retval = m_input_queue.front ();
1044 m_input_queue.pop ();
1046 if (m_input_queue.empty ())
1052 const std::string file_reader::s_in_src (
"file");
1055 file_reader::get_input (
const std::string& ,
bool& eof)
1061 std::string src_str =
fgets (m_file, eof);
1063 std::string mfile_encoding;
1065 if (m_encoding.empty ())
1067 input_system& input_sys = m_interpreter.get_input_system ();
1071 mfile_encoding = m_encoding;
1073 std::string encoding;
1074 if (mfile_encoding.compare (
"system") == 0)
1078 std::transform (encoding.begin (), encoding.end (), encoding.begin (),
1082 encoding = mfile_encoding;
1084 if (encoding.compare (
"utf-8") == 0)
1087 if (src_str.compare (0, 3,
"\xef\xbb\xbf") == 0)
1088 src_str.erase (0, 3);
1094 "Invalid UTF-8 byte sequences have been replaced.");
1099 const char *src = src_str.c_str ();
1100 std::size_t srclen = src_str.length ();
1109 error (
"file_reader::get_input: "
1110 "converting from codepage '%s' to UTF-8: %s",
1111 encoding.c_str (), std::strerror (errno));
1115 src_str = std::string (
reinterpret_cast<char *
> (utf8_str), length);
1121 const std::string eval_string_reader::s_in_src (
"eval_string");
1124 eval_string_reader::get_input (
const std::string& ,
bool& eof)
1132 retval = m_eval_string;
1138 if (retval.empty ())
1144 DEFMETHOD (input, interp, args, nargout,
1183 int nargin = args.
length ();
1185 if (nargin < 1 || nargin > 2)
1207 int nargin = args.
length ();
1217 prompt = args(0).xstring_value (
"yes_or_no: PROMPT must be a string");
1240 int nargin = args.
length ();
1250 = args(0).xstring_value (
"keyboard: PROMPT must be a string");
1260 DEFUN (completion_matches, args, nargout,
1287 std::string hint = args(0).string_value ();
1297 std::string cmd = generate_completion (hint, k);
1318 if (! list.empty ())
1329 int len = list.numel ();
1331 for (
int i = 0; i <
len; i++)
1355 DEFUN (readline_read_init_file, args, ,
1369 int nargin = args.
length ();
1378 std::string file = args(0).string_value ();
1386 DEFUN (readline_re_read_init_file, args, ,
1404 DEFMETHOD (add_input_event_hook, interp, args, ,
1424 int nargin = args.
length ();
1426 if (nargin < 1 || nargin > 2)
1432 user_data = args(1);
1440 return ovl (hook_fcn.
id ());
1443 DEFMETHOD (remove_input_event_hook, interp, args, ,
1453 int nargin = args.
length ();
1455 if (nargin < 1 || nargin > 2)
1458 std::string hook_fcn_id = args(0).xstring_value (
"remove_input_event_hook: argument not valid as a hook function name or id");
1460 bool warn = (nargin < 2);
1465 warning (
"remove_input_event_hook: %s not found in list",
1466 hook_fcn_id.c_str ());
1510 return interp.
PS1 (args, nargout);
1532 return interp.
PS2 (args, nargout);
1535 DEFMETHOD (completion_append_char, interp, args, nargout,
1555 DEFMETHOD (__request_drawnow__,, args, ,
1562 int nargin = args.
length ();
1575 DEFMETHOD (__gud_mode__, interp, args, nargout,
1583 return input_sys.
gud_mode (args, nargout);
1586 DEFMETHOD (mfile_encoding, interp, args, nargout,
1619 DEFALIAS (__mfile_encoding__, mfile_encoding);
1621 DEFMETHOD (dir_encoding, interp, args, nargout,
1662 int nargin = args.
length ();
1664 if (nargin < 1 || nargin > 2)
1668 = args(0).xstring_value (
"dir_encoding: DIR must be a string");
1679 std::string encoding
1680 = args(1).xstring_value (
"dir_encoding: ENCODING must be a string");
1685 return ovl (retval);
1689 DEFMETHOD (auto_repeat_debug_command, interp, args, nargout,
1708 OCTAVE_END_NAMESPACE(
octave)
octave_value_list Fdrawnow(octave::interpreter &, const octave_value_list &=octave_value_list(), int=0)
octave_value_list F__event_manager_gui_preference__(octave::interpreter &, const octave_value_list &=octave_value_list(), int=0)
charNDArray max(char d, const charNDArray &m)
void add(F &&fcn, Args &&... args)
void run(std::size_t num)
std::string octave_gets(const std::string &prompt, bool &eof)
interpreter & m_interpreter
static void set_quoting_function(quoting_fcn f)
static void set_completer_quote_characters(const std::string &s)
static string_vector generate_filename_completions(const std::string &text)
static char get_prev_char(int)
static void set_filename_quote_characters(const std::string &s)
static std::string readline(const std::string &prompt)
static void set_name(const std::string &n)
static void set_completer_word_break_characters(const std::string &s)
static void set_basic_word_break_characters(const std::string &s)
static void force_default_editor()
static void set_completion_function(completion_fcn f)
static void set_completion_append_character(char c)
static std::string get_line_buffer()
static void add_event_hook(event_hook_fcn f)
static void set_basic_quote_characters(const std::string &s)
static void re_read_init_file()
static void read_init_file(const std::string &file="")
static bool add(const std::string &)
void set_discard_warning_messages(bool flag)
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)
void exit_debugger_event()
map_type::iterator iterator
void run(const octave_value_list &initial_args=octave_value_list())
iterator find(const std::string &id)
void insert(const std::string &id, const hook_function &f)
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()
input_system & get_input_system()
output_system & get_output_system()
octave_value PS1(const octave_value_list &args, int nargout)
bool is_variable(const std::string &name) const
tree_evaluator & get_evaluator()
load_path & get_load_path()
error_system & get_error_system()
void recover_from_exception()
octave_value PS2(const octave_value_list &args, int nargout)
octave_idx_type length() const
bool is_classdef_object() const
string_vector map_keys() const
string_vector & append(const std::string &s)
string_vector & sort(bool make_uniq=false)
octave_idx_type numel() const
void keyboard(const std::string &prompt="keyboard> ")
bool in_debug_repl() const
OCTAVE_BEGIN_NAMESPACE(octave) static octave_value daspk_fcn
#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.
#define DEFALIAS(alias, name)
Macro to define an alias for another existing function name.
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,...)
std::string dir_sep_chars()
ColumnVector transform(const Matrix &m, double x, double y, double z)
string_vector make_name_list()
int octave_iconv_close_wrapper(void *cd)
void * octave_iconv_open_wrapper(const char *tocode, const char *fromcode)
interpreter & __get_interpreter__()
input_system & __get_input_system__()
std::string fgets(FILE *f)
const char * octave_locale_charset_wrapper(void)
std::string canonicalize_file_name(const std::string &name)
octave_value set_internal_variable(bool &var, const octave_value_list &args, int nargout, const char *nm)
unsigned int u8_validate(const std::string &who, std::string &in_string, const u8_fallback_type type=U8_REPLACEMENT_CHAR)
octave_value_list ovl(const OV_Args &... args)
Construct an octave_value_list with less typing.
int pipe_handler_error_count
uint8_t * octave_u8_conv_from_encoding(const char *fromcode, const char *src, size_t srclen, size_t *lengthp)