GNU Octave  3.8.0
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
cmd-edit.cc
Go to the documentation of this file.
1 /*
2 
3 Copyright (C) 1996-2013 John W. Eaton
4 
5 This file is part of Octave.
6 
7 Octave is free software; you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published by the
9 Free Software Foundation; either version 3 of the License, or (at your
10 option) any later version.
11 
12 Octave is distributed in the hope that it will be useful, but WITHOUT
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 for more details.
16 
17 You should have received a copy of the GNU General Public License
18 along with Octave; see the file COPYING. If not, see
19 <http://www.gnu.org/licenses/>.
20 
21 */
22 
23 #ifdef HAVE_CONFIG_H
24 #include <config.h>
25 #endif
26 
27 #include <cstdlib>
28 #include <cstring>
29 
30 #include <string>
31 
32 #include <sys/types.h>
33 #include <unistd.h>
34 
35 #include "quit.h"
36 
37 #include "cmd-edit.h"
38 #include "cmd-hist.h"
39 #include "file-ops.h"
40 #include "lo-error.h"
41 #include "lo-utils.h"
42 #include "oct-env.h"
43 #include "oct-mutex.h"
44 #include "oct-time.h"
45 #include "singleton-cleanup.h"
46 
48 
49 std::set<command_editor::startup_hook_fcn> command_editor::startup_hook_set;
50 
51 std::set<command_editor::pre_input_hook_fcn> command_editor::pre_input_hook_set;
52 
53 std::set<command_editor::event_hook_fcn> command_editor::event_hook_set;
54 
56 
57 #if defined (USE_READLINE)
58 
59 #include <cstdio>
60 #include <cstdlib>
61 
62 #include "oct-rl-edit.h"
63 
64 class
66 {
67 public:
68 
69  typedef command_editor::startup_hook_fcn startup_hook_fcn;
70 
71  typedef command_editor::pre_input_hook_fcn pre_input_hook_fcn;
72 
73  typedef command_editor::event_hook_fcn event_hook_fcn;
74 
75  typedef command_editor::completion_fcn completion_fcn;
76 
77  gnu_readline (void);
78 
79  ~gnu_readline (void) { }
80 
81  void do_set_name (const std::string& n);
82 
83  std::string do_readline (const std::string& prompt, bool& eof);
84 
85  void do_set_input_stream (FILE *f);
86 
87  FILE *do_get_input_stream (void);
88 
89  void do_set_output_stream (FILE *f);
90 
91  FILE *do_get_output_stream (void);
92 
93  void do_redisplay (void);
94 
95  int do_terminal_rows (void);
96 
97  int do_terminal_cols (void);
98 
99  void do_clear_screen (bool skip_redisplay);
100 
101  void do_resize_terminal (void);
102 
103  std::string newline_chars (void);
104 
105  void do_restore_terminal_state (void);
106 
107  void do_blink_matching_paren (bool flag);
108 
109  void do_set_basic_word_break_characters (const std::string& s);
110 
111  void do_set_completer_word_break_characters (const std::string& s);
112 
113  void do_set_basic_quote_characters (const std::string& s);
114 
115  void do_set_filename_quote_characters (const std::string& s);
116 
117  void do_set_completer_quote_characters (const std::string& s);
118 
119  void do_set_completion_append_character (char c);
120 
121  void do_set_completion_function (completion_fcn f);
122 
123  void do_set_quoting_function (quoting_fcn f);
124 
125  void do_set_dequoting_function (dequoting_fcn f);
126 
127  void do_set_char_is_quoted_function (char_is_quoted_fcn f);
128 
129  void do_set_user_accept_line_function (user_accept_line_fcn f);
130 
131  completion_fcn do_get_completion_function (void) const;
132 
133  quoting_fcn do_get_quoting_function (void) const;
134 
135  dequoting_fcn do_get_dequoting_function (void) const;
136 
137  char_is_quoted_fcn do_get_char_is_quoted_function (void) const;
138 
139  user_accept_line_fcn do_get_user_accept_line_function (void) const;
140 
142  do_generate_filename_completions (const std::string& text);
143 
144  std::string do_get_line_buffer (void) const;
145 
146  std::string do_get_current_line (void) const;
147 
148  void do_replace_line (const std::string& text, bool clear_undo);
149 
150  void do_insert_text (const std::string& text);
151 
152  void do_newline (void);
153 
154  void do_accept_line (void);
155 
156  bool do_undo (void);
157 
158  void do_clear_undo_list (void);
159 
160  void set_startup_hook (startup_hook_fcn f);
161 
162  void restore_startup_hook (void);
163 
164  void set_pre_input_hook (pre_input_hook_fcn f);
165 
166  void restore_pre_input_hook (void);
167 
168  void set_event_hook (event_hook_fcn f);
169 
170  void restore_event_hook (void);
171 
172  void do_restore_event_hook (void);
173 
174  void do_read_init_file (const std::string& file);
175 
176  void do_re_read_init_file (void);
177 
178  bool do_filename_completion_desired (bool);
179 
180  bool do_filename_quoting_desired (bool);
181 
182  void do_interrupt (bool);
183 
184  static int operate_and_get_next (int, int);
185 
186  static int history_search_backward (int, int);
187 
188  static int history_search_forward (int, int);
189 
190 private:
191 
192  startup_hook_fcn previous_startup_hook;
193 
194  pre_input_hook_fcn previous_pre_input_hook;
195 
196  event_hook_fcn previous_event_hook;
197 
198  completion_fcn completion_function;
199 
200  quoting_fcn quoting_function;
201 
202  dequoting_fcn dequoting_function;
203 
204  char_is_quoted_fcn char_is_quoted_function;
205 
206  user_accept_line_fcn user_accept_line_function;
207 
208  static char *command_generator (const char *text, int state);
209 
210  static char *command_quoter (char *text, int match_type, char *quote_pointer);
211  static char *command_dequoter (char *text, int match_type);
212 
213  static int command_char_is_quoted (char *text, int index);
214 
215  static int command_accept_line (int count, int key);
216 
217  static char **command_completer (const char *text, int start, int end);
218 };
219 
221  : command_editor (), previous_startup_hook (0),
222  previous_pre_input_hook (0),
223  previous_event_hook (0), completion_function (0),
224  quoting_function (0), dequoting_function (0),
225  char_is_quoted_function (0), user_accept_line_function (0)
226 {
227  // FIXME: need interface to rl_add_defun, rl_initialize, and
228  // a function to set rl_terminal_name
229 
230  std::string term = octave_env::getenv ("TERM");
231 
232  octave_rl_set_terminal_name (term.c_str ());
233 
235 
236  do_blink_matching_paren (true);
237 
238  // Bind operate-and-get-next.
239 
240  octave_rl_add_defun ("operate-and-get-next",
241  gnu_readline::operate_and_get_next,
242  octave_rl_ctrl ('O'));
243 
244  // And the history search functions.
245 
246  octave_rl_add_defun ("history-search-backward",
247  gnu_readline::history_search_backward,
248  octave_rl_meta ('P'));
249 
250  octave_rl_add_defun ("history-search-forward",
251  gnu_readline::history_search_forward,
252  octave_rl_meta ('N'));
253 }
254 
255 void
256 gnu_readline::do_set_name (const std::string& nm)
257 {
258  ::octave_rl_set_name (nm.c_str ());
259 }
260 
261 std::string
262 gnu_readline::do_readline (const std::string& prompt, bool& eof)
263 {
264  std::string retval;
265 
266  eof = false;
267 
268  char *line = 0;
269 
270  const char *p = prompt.c_str ();
271 
273 
274  line = ::octave_rl_readline (p);
275 
277 
278  if (line)
279  {
280  retval = line;
281 
282  free (line);
283  }
284  else
285  eof = true;
286 
287  return retval;
288 }
289 
290 void
291 gnu_readline::do_set_input_stream (FILE *f)
292 {
294 }
295 
296 FILE *
297 gnu_readline::do_get_input_stream (void)
298 {
300 }
301 
302 void
303 gnu_readline::do_set_output_stream (FILE *f)
304 {
306 }
307 
308 FILE *
309 gnu_readline::do_get_output_stream (void)
310 {
312 }
313 
314 void
315 gnu_readline::do_redisplay (void)
316 {
318 }
319 
320 // GNU readline handles SIGWINCH, so these values have a good chance
321 // of being correct even if the window changes size (they may be
322 // wrong if, for example, the luser changes the window size while the
323 // pager is running, and the signal is handled by the pager instead of
324 // us.
325 
326 int
327 gnu_readline::do_terminal_rows (void)
328 {
329  int sh = ::octave_rl_screen_height ();
330 
331  return sh > 0 ? sh : 24;
332 }
333 
334 int
335 gnu_readline::do_terminal_cols (void)
336 {
337  int sw = ::octave_rl_screen_width ();
338 
339  return sw > 0 ? sw : 80;
340 }
341 
342 void
343 gnu_readline::do_clear_screen (bool skip_redisplay)
344 {
345  ::octave_rl_clear_screen (skip_redisplay);
346 }
347 
348 void
349 gnu_readline::do_resize_terminal (void)
350 {
352 }
353 
354 std::string
355 gnu_readline::newline_chars (void)
356 {
357  return "\r\n";
358 }
359 
360 void
361 gnu_readline::do_restore_terminal_state (void)
362 {
364 }
365 
366 void
367 gnu_readline::do_blink_matching_paren (bool flag)
368 {
369  ::octave_rl_enable_paren_matching (flag ? 1 : 0);
370 }
371 
372 void
373 gnu_readline::do_set_basic_word_break_characters (const std::string& s)
374 {
376 }
377 
378 void
379 gnu_readline::do_set_completer_word_break_characters (const std::string& s)
380 {
382 }
383 
384 void
385 gnu_readline::do_set_basic_quote_characters (const std::string& s)
386 {
388 }
389 
390 void
391 gnu_readline::do_set_filename_quote_characters (const std::string& s)
392 {
394 }
395 
396 void
397 gnu_readline::do_set_completer_quote_characters (const std::string& s)
398 {
400 }
401 
402 void
403 gnu_readline::do_set_completion_append_character (char c)
404 {
406 }
407 
408 void
409 gnu_readline::do_set_completion_function (completion_fcn f)
410 {
411  completion_function = f;
412 
414  = f ? gnu_readline::command_completer : 0;
415 
417 }
418 
419 void
420 gnu_readline::do_set_quoting_function (quoting_fcn f)
421 {
422  quoting_function = f;
423 
425  = f ? gnu_readline::command_quoter : 0;
426 
428 }
429 
430 void
431 gnu_readline::do_set_dequoting_function (dequoting_fcn f)
432 {
433  dequoting_function = f;
434 
436  = f ? gnu_readline::command_dequoter : 0;
437 
439 }
440 
441 void
442 gnu_readline::do_set_char_is_quoted_function (char_is_quoted_fcn f)
443 {
444  char_is_quoted_function = f;
445 
447  = f ? gnu_readline::command_char_is_quoted : 0;
448 
450 }
451 
452 void
453 gnu_readline::do_set_user_accept_line_function (user_accept_line_fcn f)
454 {
455  user_accept_line_function = f;
456 
457  if (f)
458  octave_rl_add_defun ("accept-line", gnu_readline::command_accept_line,
459  ::octave_rl_ctrl ('M'));
460  else
461  octave_rl_add_defun ("accept-line", ::octave_rl_newline,
462  ::octave_rl_ctrl ('M'));
463 }
464 
465 gnu_readline::completion_fcn
466 gnu_readline::do_get_completion_function (void) const
467 {
468  return completion_function;
469 }
470 
471 gnu_readline::quoting_fcn
472 gnu_readline::do_get_quoting_function (void) const
473 {
474  return quoting_function;
475 }
476 
477 gnu_readline::dequoting_fcn
478 gnu_readline::do_get_dequoting_function (void) const
479 {
480  return dequoting_function;
481 }
482 
483 gnu_readline::char_is_quoted_fcn
484 gnu_readline::do_get_char_is_quoted_function (void) const
485 {
486  return char_is_quoted_function;
487 }
488 
489 gnu_readline::user_accept_line_fcn
490 gnu_readline::do_get_user_accept_line_function (void) const
491 {
492  return user_accept_line_function;
493 }
494 
496 gnu_readline::do_generate_filename_completions (const std::string& text)
497 {
498  string_vector retval;
499 
500  int n = 0;
501  int count = 0;
502 
503  char *fn = 0;
504 
505  while (1)
506  {
507  fn = ::octave_rl_filename_completion_function (text.c_str (), count);
508 
509  if (fn)
510  {
511  if (count == n)
512  {
513  // Famous last words: Most large directories will not
514  // have more than a few hundred files, so we should not
515  // resize too many times even if the growth is linear...
516 
517  n += 100;
518  retval.resize (n);
519  }
520 
521  retval[count++] = fn;
522 
523  free (fn);
524  }
525  else
526  break;
527  }
528 
529  retval.resize (count);
530 
531  return retval;
532 }
533 
534 std::string
535 gnu_readline::do_get_line_buffer (void) const
536 {
538 }
539 
540 std::string
541 gnu_readline::do_get_current_line (void) const
542 {
543  std::string retval;
544  char *buf = ::octave_rl_copy_line ();
545  retval = buf;
546  free (buf);
547  return retval;
548 }
549 
550 void
551 gnu_readline::do_replace_line (const std::string& text, bool clear_undo)
552 {
553  ::octave_rl_replace_line (text.c_str (), clear_undo);
554 }
555 
556 void
557 gnu_readline::do_insert_text (const std::string& text)
558 {
559  ::octave_rl_insert_text (text.c_str ());
560 }
561 
562 void
563 gnu_readline::do_newline (void)
564 {
565  ::octave_rl_newline (1, '\n');
566 }
567 
568 void
569 gnu_readline::do_accept_line (void)
570 {
571  command_accept_line (1, '\n');
572 }
573 
574 bool
575 gnu_readline::do_undo (void)
576 {
578 }
579 
580 void
581 gnu_readline::do_clear_undo_list ()
582 {
584 }
585 
586 void
587 gnu_readline::set_startup_hook (startup_hook_fcn f)
588 {
589  previous_startup_hook = ::octave_rl_get_startup_hook ();
590 
591  if (f != previous_startup_hook)
593 }
594 
595 void
596 gnu_readline::restore_startup_hook (void)
597 {
598  ::octave_rl_set_startup_hook (previous_startup_hook);
599 }
600 
601 void
602 gnu_readline::set_pre_input_hook (pre_input_hook_fcn f)
603 {
604  previous_pre_input_hook = ::octave_rl_get_pre_input_hook ();
605 
606  if (f != previous_pre_input_hook)
608 }
609 
610 void
611 gnu_readline::restore_pre_input_hook (void)
612 {
613  ::octave_rl_set_pre_input_hook (previous_pre_input_hook);
614 }
615 
616 void
617 gnu_readline::set_event_hook (event_hook_fcn f)
618 {
619  previous_event_hook = octave_rl_get_event_hook ();
620 
622 }
623 
624 void
625 gnu_readline::restore_event_hook (void)
626 {
627  ::octave_rl_set_event_hook (previous_event_hook);
628 }
629 
630 void
631 gnu_readline::do_read_init_file (const std::string& file)
632 {
633  ::octave_rl_read_init_file (file.c_str ());
634 }
635 
636 void
637 gnu_readline::do_re_read_init_file (void)
638 {
640 }
641 
642 bool
643 gnu_readline::do_filename_completion_desired (bool arg)
644 {
646 }
647 
648 bool
649 gnu_readline::do_filename_quoting_desired (bool arg)
650 {
652 }
653 
654 void
655 gnu_readline::do_interrupt (bool arg)
656 {
657  ::octave_rl_done (arg);
658 }
659 
660 int
661 gnu_readline::operate_and_get_next (int /* count */, int /* c */)
662 {
663  // Accept the current line.
664 
666 
667  // Find the current line, and find the next line to use.
668 
669  int x_where = command_history::where ();
670 
671  int x_length = command_history::length ();
672 
674  && (x_length >= command_history::max_input_history ()))
675  || (x_where >= x_length - 1))
676  command_history::set_mark (x_where);
677  else
678  command_history::set_mark (x_where + 1);
679 
681 
682  return 0;
683 }
684 
685 int
686 gnu_readline::history_search_backward (int count, int c)
687 {
688  return octave_rl_history_search_backward (count, c);
689 }
690 
691 int
692 gnu_readline::history_search_forward (int count, int c)
693 {
694  return octave_rl_history_search_forward (count, c);
695 }
696 
697 char *
698 gnu_readline::command_generator (const char *text, int state)
699 {
700  char *retval = 0;
701 
702  completion_fcn f = command_editor::get_completion_function ();
703 
704  std::string tmp = f (text, state);
705 
706  size_t len = tmp.length ();
707 
708  if (len > 0)
709  {
710  retval = static_cast<char *> (gnulib::malloc (len+1));
711 
712  strcpy (retval, tmp.c_str ());
713  }
714 
715  return retval;
716 }
717 
718 char *
719 gnu_readline::command_quoter (char *text, int matches, char *qcp)
720 {
721  char *retval = 0;
722 
723  quoting_fcn f = command_editor::get_quoting_function ();
724 
725  std::string tmp = f (text, matches, *qcp);
726 
727  size_t len = tmp.length ();
728 
729  if (len > 0)
730  {
731  retval = static_cast<char *> (gnulib::malloc (len+1));
732 
733  strcpy (retval, tmp.c_str ());
734  }
735 
736  return retval;
737 }
738 
739 char *
740 gnu_readline::command_dequoter (char *text, int quote)
741 {
742  char *retval = 0;
743 
744  dequoting_fcn f = command_editor::get_dequoting_function ();
745 
746  std::string tmp = f (text, quote);
747 
748  size_t len = tmp.length ();
749 
750  if (len > 0)
751  {
752  retval = static_cast<char *> (gnulib::malloc (len+1));
753 
754  strcpy (retval, tmp.c_str ());
755  }
756 
757  return retval;
758 }
759 
760 int
761 gnu_readline::command_char_is_quoted (char *text, int quote)
762 {
763  char_is_quoted_fcn f = command_editor::get_char_is_quoted_function ();
764 
765  return f (text, quote);
766 }
767 
768 int
769 gnu_readline::command_accept_line (int count, int key)
770 {
771  user_accept_line_fcn f = command_editor::get_user_accept_line_function ();
772 
773  if (f)
774  f (::octave_rl_line_buffer ());
775 
777 
778  return ::octave_rl_newline (count, key);
779 }
780 
781 char **
782 gnu_readline::command_completer (const char *text, int, int)
783 {
784  char **matches = 0;
785  matches
786  = ::octave_rl_completion_matches (text, gnu_readline::command_generator);
787  return matches;
788 }
789 
790 #endif
791 
792 class
794 {
795 public:
796 
798  : command_editor (), input_stream (stdin), output_stream (stdout) { }
799 
801 
802  std::string do_readline (const std::string& prompt, bool& eof);
803 
804  void do_set_input_stream (FILE *f);
805 
806  FILE *do_get_input_stream (void);
807 
808  void do_set_output_stream (FILE *f);
809 
810  FILE *do_get_output_stream (void);
811 
812  string_vector do_generate_filename_completions (const std::string& text);
813 
814  std::string do_get_line_buffer (void) const;
815 
816  std::string do_get_current_line (void) const;
817 
818  void do_replace_line (const std::string& text, bool clear_undo);
819 
820  void do_insert_text (const std::string& text);
821 
822  void do_newline (void);
823 
824  void do_accept_line (void);
825 
826 private:
827 
829 
831 
832  // No copying!
833 
835 
836  default_command_editor& operator = (const default_command_editor&);
837 };
838 
839 std::string
840 default_command_editor::do_readline (const std::string& prompt, bool& eof)
841 {
842  gnulib::fputs (prompt.c_str (), output_stream);
843  gnulib::fflush (output_stream);
844 
845  return octave_fgetl (input_stream, eof);
846 }
847 
848 void
850 {
851  input_stream = f;
852 }
853 
854 FILE *
856 {
857  return input_stream;
858 }
859 
860 void
862 {
863  output_stream = f;
864 }
865 
866 FILE *
868 {
869  return output_stream;
870 }
871 
874 {
875  // FIXME
876  return string_vector ();
877 }
878 
879 std::string
881 {
882  return "";
883 }
884 
885 std::string
887 {
888  // FIXME
889  return std::string ();
890 }
891 
892 void
893 default_command_editor::do_replace_line (const std::string&, bool)
894 {
895  // FIXME
896 }
897 
898 void
900 {
901  // FIXME
902 }
903 
904 void
906 {
907  // FIXME
908 }
909 
910 void
912 {
913  // FIXME
914 }
915 
916 bool
918 {
919  bool retval = true;
920 
921  if (! instance)
922  {
924 
925  if (instance)
927  }
928 
929  if (! instance)
930  {
932  ("unable to create command history object!");
933 
934  retval = false;
935  }
936 
937  return retval;
938 }
939 
940 void
942 {
943 #if defined (USE_READLINE)
944  instance = new gnu_readline ();
945 #else
947 #endif
948 }
949 
950 void
952 {
953  delete instance;
955 }
956 
957 void
958 command_editor::set_initial_input (const std::string& text)
959 {
960  if (instance_ok ())
961  instance->initial_input = text;
962 }
963 
964 int
966 {
967  return instance_ok () ? instance->do_insert_initial_input () : 0;
968 }
969 
970 int
972 {
974  p != startup_hook_set.end (); p++)
975  {
976  startup_hook_fcn f = *p;
977 
978  if (f)
979  f ();
980  }
981 
982  return 0;
983 }
984 
985 int
987 {
989  p != pre_input_hook_set.end (); p++)
990  {
991  pre_input_hook_fcn f = *p;
992 
993  if (f)
994  f ();
995  }
996 
997  return 0;
998 }
999 
1000 int
1002 {
1003  event_hook_lock.lock ();
1004 
1005  std::set<event_hook_fcn> hook_set (event_hook_set);
1006 
1007  event_hook_lock.unlock ();
1008 
1009  for (event_hook_set_iterator p = hook_set.begin ();
1010  p != hook_set.end (); p++)
1011  {
1012  event_hook_fcn f = *p;
1013 
1014  if (f)
1015  f ();
1016  }
1017 
1018  return 0;
1019 }
1020 
1021 void
1022 command_editor::set_name (const std::string& n)
1023 {
1024  if (instance_ok ())
1025  instance->do_set_name (n);
1026 }
1027 
1028 std::string
1029 command_editor::readline (const std::string& prompt)
1030 {
1031  bool eof;
1032 
1033  return readline (prompt, eof);
1034 }
1035 
1036 std::string
1037 command_editor::readline (const std::string& prompt, bool& eof)
1038 {
1039  std::string retval;
1040 
1041  if (instance_ok ())
1042  {
1043  if (! instance->initial_input.empty ())
1045 
1046  retval = instance->do_readline (prompt, eof);
1047  }
1048 
1049  return retval;
1050 }
1051 
1052 void
1054 {
1055  if (instance_ok ())
1057 }
1058 
1059 FILE *
1061 {
1062  return (instance_ok ())
1063  ? instance->do_get_input_stream () : 0;
1064 }
1065 
1066 void
1068 {
1069  if (instance_ok ())
1071 }
1072 
1073 FILE *
1075 {
1076  return (instance_ok ())
1077  ? instance->do_get_output_stream () : 0;
1078 }
1079 
1080 void
1082 {
1083  if (instance_ok ())
1084  instance->do_redisplay ();
1085 }
1086 
1087 int
1089 {
1090  return (instance_ok ())
1091  ? instance->do_terminal_rows () : -1;
1092 }
1093 
1094 int
1096 {
1097  return (instance_ok ())
1098  ? instance->do_terminal_cols () : -1;
1099 }
1100 
1101 void
1102 command_editor::clear_screen (bool skip_redisplay)
1103 {
1104  if (instance_ok ())
1105  instance->do_clear_screen (skip_redisplay);
1106 }
1107 
1108 void
1110 {
1111  if (instance_ok ())
1113 }
1114 
1115 std::string
1117 {
1118  return (instance_ok ())
1119  ? instance->do_decode_prompt_string (s) : std::string ();
1120 }
1121 
1122 int
1124 {
1125  return (instance_ok ())
1126  ? instance->command_number : 0;
1127 }
1128 
1129 void
1131 {
1132  if (instance_ok ())
1133  instance->command_number = n;
1134 }
1135 
1136 void
1138 {
1139  if (instance_ok ())
1141 }
1142 
1143 void
1145 {
1146  if (instance_ok ())
1148 }
1149 
1150 void
1152 {
1153  if (instance_ok ())
1155 }
1156 
1157 void
1159 {
1160  if (instance_ok ())
1162 }
1163 
1164 void
1166 {
1167  if (instance_ok ())
1169 }
1170 
1171 void
1173 {
1174  if (instance_ok ())
1176 }
1177 
1178 void
1180 {
1181  if (instance_ok ())
1183 }
1184 
1185 void
1187 {
1188  if (instance_ok ())
1190 }
1191 
1192 void
1194 {
1195  if (instance_ok ())
1197 }
1198 
1199 void
1201 {
1202  if (instance_ok ())
1204 }
1205 
1206 void
1208 {
1209  if (instance_ok ())
1211 }
1212 
1213 void
1215 {
1216  if (instance_ok ())
1218 }
1219 
1220 void
1222 {
1223  if (instance_ok ())
1225 }
1226 
1227 void
1229 {
1230  if (instance_ok ())
1232 }
1233 
1236 {
1237  return (instance_ok ())
1239 }
1240 
1243 {
1244  return (instance_ok ())
1246 }
1247 
1250 {
1251  return (instance_ok ())
1253 }
1254 
1257 {
1258  return (instance_ok ())
1260 }
1261 
1264 {
1265  return (instance_ok ())
1267 }
1268 
1271 {
1272  return (instance_ok ())
1274 }
1275 
1276 std::string
1278 {
1279  return (instance_ok ()) ? instance->do_get_line_buffer () : "";
1280 }
1281 
1282 std::string
1284 {
1285  return (instance_ok ()) ? instance->do_get_current_line () : "";
1286 }
1287 
1288 void
1289 command_editor::replace_line (const std::string& text, bool clear_undo)
1290 {
1291  if (instance_ok ())
1292  instance->do_replace_line (text, clear_undo);
1293 }
1294 
1295 void
1296 command_editor::insert_text (const std::string& text)
1297 {
1298  if (instance_ok ())
1299  instance->do_insert_text (text);
1300 }
1301 
1302 void
1304 {
1305  if (instance_ok ())
1306  instance->do_newline ();
1307 }
1308 
1309 void
1311 {
1312  if (instance_ok ())
1314 }
1315 
1316 bool
1318 {
1319  return instance_ok () ? instance->do_undo () : false;
1320 }
1321 
1322 void
1324 {
1325  if (instance_ok ())
1327 }
1328 
1329 void
1331 {
1332  if (instance_ok ())
1333  {
1334  startup_hook_set.insert (f);
1335 
1337  }
1338 }
1339 
1340 void
1342 {
1343  if (instance_ok ())
1344  {
1346 
1347  if (p != startup_hook_set.end ())
1348  startup_hook_set.erase (p);
1349 
1350  if (startup_hook_set.empty ())
1352  }
1353 }
1354 
1355 void
1357 {
1358  if (instance_ok ())
1359  {
1360  pre_input_hook_set.insert (f);
1361 
1363  }
1364 }
1365 
1366 void
1368 {
1369  if (instance_ok ())
1370  {
1372 
1373  if (p != pre_input_hook_set.end ())
1374  pre_input_hook_set.erase (p);
1375 
1376  if (pre_input_hook_set.empty ())
1378  }
1379 }
1380 
1381 void
1383 {
1384  octave_autolock guard (event_hook_lock);
1385 
1386  if (instance_ok ())
1387  {
1388  event_hook_set.insert (f);
1389 
1391  }
1392 }
1393 
1394 void
1396 {
1397  octave_autolock guard (event_hook_lock);
1398 
1399  if (instance_ok ())
1400  {
1402 
1403  if (p != event_hook_set.end ())
1404  event_hook_set.erase (p);
1405 
1406  if (event_hook_set.empty ())
1408  }
1409 }
1410 
1411 void
1413 {
1414  event_handler ();
1415 }
1416 
1417 void
1418 command_editor::read_init_file (const std::string& file_arg)
1419 {
1420  if (instance_ok ())
1421  {
1422  std::string file = file_ops::tilde_expand (file_arg);
1423 
1424  instance->do_read_init_file (file);
1425  }
1426 }
1427 
1428 void
1430 {
1431  if (instance_ok ())
1433 }
1434 
1435 bool
1437 {
1438  return (instance_ok ())
1439  ? instance->do_filename_completion_desired (arg) : false;
1440 }
1441 
1442 bool
1444 {
1445  return (instance_ok ())
1446  ? instance->do_filename_quoting_desired (arg) : false;
1447 }
1448 
1449 bool
1451 {
1452  bool retval;
1453 
1454  if (instance_ok ())
1455  {
1456  // Return the current interrupt state.
1457  retval = instance->interrupted;
1458 
1459  instance->do_interrupt (arg);
1460 
1462  }
1463  else
1464  retval = false;
1465 
1466  return retval;
1467 }
1468 
1469 // Return a string which will be printed as a prompt. The string may
1470 // contain special characters which are decoded as follows:
1471 //
1472 // \a bell (ascii 07)
1473 // \d the date
1474 // \e escape (ascii 033)
1475 // \h the hostname up to the first '.'
1476 // \H the hostname
1477 // \n CRLF
1478 // \r CR
1479 // \s the name of the shell (program)
1480 // \t the time
1481 // \T the time in 12-hour hh:mm:ss format
1482 // \@ the time in 12-hour hh:mm am/pm format
1483 // \A the time in 24-hour hh:mm format
1484 // \u your username
1485 // \w the current working directory
1486 // \W the last element of PWD
1487 // \! the history number of this command
1488 // \# the command number of this command
1489 // \$ a $ or a # if you are root
1490 // \nnn character code nnn in octal
1491 // \\ a backslash
1492 // \[ begin a sequence of non-printing chars
1493 // \] end a sequence of non-printing chars
1494 
1495 std::string
1497 {
1498  std::string result;
1499  std::string temp;
1500  size_t i = 0;
1501  size_t slen = s.length ();
1502  int c;
1503 
1504  while (i < slen)
1505  {
1506  c = s[i];
1507 
1508  i++;
1509 
1510  if (c == '\\')
1511  {
1512  c = s[i];
1513 
1514  switch (c)
1515  {
1516  case '0':
1517  case '1':
1518  case '2':
1519  case '3':
1520  case '4':
1521  case '5':
1522  case '6':
1523  case '7':
1524  // Maybe convert an octal number.
1525  {
1526  int n = read_octal (s.substr (i, 3));
1527 
1528  temp = "\\";
1529 
1530  if (n != -1)
1531  {
1532  i += 3;
1533  temp[0] = n;
1534  }
1535 
1536  c = 0;
1537  goto add_string;
1538  }
1539 
1540  case 'a':
1541  {
1542  temp = '\a';
1543 
1544  goto add_string;
1545  }
1546 
1547  case 'e':
1548  {
1549  temp = '\033';
1550 
1551  goto add_string;
1552  }
1553 
1554  case 'r':
1555  {
1556  temp = '\r';
1557 
1558  goto add_string;
1559  }
1560 
1561  case 'd':
1562  case 't':
1563  case 'T':
1564  case '@':
1565  case 'A':
1566  // Make the current time/date into a string.
1567  {
1568  octave_localtime now;
1569 
1570  if (c == 'd')
1571  temp = now.strftime ("%a %b %d");
1572  else if (c == 't')
1573  temp = now.strftime ("%H:%M:%S");
1574  else if (c == 'T')
1575  temp = now.strftime ("%I:%M:%S");
1576  else if (c == '@')
1577  temp = now.strftime ("%I:%M %p");
1578  else if (c == 'A')
1579  temp = now.strftime ("%H:%M");
1580 
1581  goto add_string;
1582  }
1583 
1584  case 'n':
1585  {
1586  temp = newline_chars ();
1587 
1588  goto add_string;
1589  }
1590 
1591  case 's':
1592  {
1593  temp = octave_env::get_program_name ();
1594  temp = octave_env::base_pathname (temp);
1595 
1596  goto add_string;
1597  }
1598 
1599  case 'w':
1600  case 'W':
1601  {
1602  try
1603  {
1605  }
1606  catch (octave_execution_exception)
1607  {
1608  temp = "";
1609  }
1610 
1611  std::string home_dir = octave_env::get_home_directory ();
1612 
1613  if (c == 'W' && (home_dir.empty () || temp != home_dir))
1614  {
1615  if (temp != "/" && temp != "//")
1616  {
1617  size_t pos = temp.rfind ('/');
1618 
1619  if (pos != std::string::npos && pos != 0)
1620  temp = temp.substr (pos + 1);
1621  }
1622  }
1623  else
1625 
1626  goto add_string;
1627  }
1628 
1629  case 'u':
1630  {
1631  temp = octave_env::get_user_name ();
1632 
1633  goto add_string;
1634  }
1635 
1636  case 'H':
1637  {
1638  temp = octave_env::get_host_name ();
1639 
1640  goto add_string;
1641  }
1642 
1643  case 'h':
1644  {
1645  temp = octave_env::get_host_name ();
1646 
1647  size_t pos = temp.find ('.');
1648 
1649  if (pos != std::string::npos)
1650  temp.resize (pos);
1651 
1652  goto add_string;
1653  }
1654 
1655  case '#':
1656  {
1657  char number_buffer[128];
1658  sprintf (number_buffer, "%d", command_number);
1659  temp = number_buffer;
1660 
1661  goto add_string;
1662  }
1663 
1664  case '!':
1665  {
1666  char number_buffer[128];
1667  int num = command_history::current_number ();
1668  if (num > 0)
1669  sprintf (number_buffer, "%d", num);
1670  else
1671  strcpy (number_buffer, "!");
1672  temp = number_buffer;
1673 
1674  goto add_string;
1675  }
1676 
1677  case '$':
1678  {
1679 #if defined (HAVE_GETEUID)
1680  temp = (::geteuid () == 0 ? "#" : "$");
1681 #else
1682  temp = "$";
1683 #endif
1684 
1685  goto add_string;
1686  }
1687 
1688 #if defined (USE_READLINE)
1689  case '[':
1690  case ']':
1691  {
1692  temp.resize (1);
1693 
1694  temp[0] = ((c == '[')
1697 
1698  goto add_string;
1699  }
1700 #endif
1701 
1702  case '\\':
1703  {
1704  temp = "\\";
1705 
1706  goto add_string;
1707  }
1708 
1709  default:
1710  {
1711  temp = "\\ ";
1712  temp[1] = c;
1713 
1714  goto add_string;
1715  }
1716 
1717  add_string:
1718  {
1719  if (c)
1720  i++;
1721 
1722  result.append (temp);
1723 
1724  break;
1725  }
1726  }
1727  }
1728  else
1729  result += c;
1730  }
1731 
1732  return result;
1733 }
1734 
1735 int
1737 {
1738  std::string input = initial_input;
1739 
1740  initial_input = "";
1741 
1742  do_insert_text (input);
1743 
1744  // Is it really right to redisplay here?
1745  do_redisplay ();
1746 
1747  return 0;
1748 }
1749 
1750 // Return the octal number parsed from STRING, or -1 to indicate that
1751 // the string contained a bad number.
1752 
1753 int
1754 command_editor::read_octal (const std::string& s)
1755 {
1756  int result = 0;
1757  int digits = 0;
1758 
1759  size_t i = 0;
1760  size_t slen = s.length ();
1761 
1762  while (i < slen && s[i] >= '0' && s[i] < '8')
1763  {
1764  digits++;
1765  result = (result * 8) + s[i] - '0';
1766  i++;
1767  }
1768 
1769  if (! digits || result > 0777 || i < slen)
1770  result = -1;
1771 
1772  return result;
1773 }
1774 
1775 void
1777 {
1778  current_liboctave_error_handler ("%s", gnulib::strerror (err_num));
1779 }
1780 
1781 void
1782 command_editor::error (const std::string& s)
1783 {
1784  current_liboctave_error_handler ("%s", s.c_str ());
1785 }