00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #ifdef HAVE_CONFIG_H
00024 #include <config.h>
00025 #endif
00026
00027 #include <cstdlib>
00028 #include <cstring>
00029
00030 #include <string>
00031
00032 #include <sys/types.h>
00033 #include <unistd.h>
00034
00035 #include "quit.h"
00036
00037 #include "cmd-edit.h"
00038 #include "cmd-hist.h"
00039 #include "file-ops.h"
00040 #include "lo-error.h"
00041 #include "lo-utils.h"
00042 #include "oct-env.h"
00043 #include "oct-mutex.h"
00044 #include "oct-time.h"
00045 #include "singleton-cleanup.h"
00046
00047 command_editor *command_editor::instance = 0;
00048
00049 std::set<command_editor::startup_hook_fcn> command_editor::startup_hook_set;
00050
00051 std::set<command_editor::event_hook_fcn> command_editor::event_hook_set;
00052
00053 static octave_mutex event_hook_lock;
00054
00055 #if defined (USE_READLINE)
00056
00057 #include <cstdio>
00058 #include <cstdlib>
00059
00060 #include "oct-rl-edit.h"
00061
00062 class
00063 gnu_readline : public command_editor
00064 {
00065 public:
00066
00067 typedef command_editor::startup_hook_fcn startup_hook_fcn;
00068
00069 typedef command_editor::event_hook_fcn event_hook_fcn;
00070
00071 typedef command_editor::completion_fcn completion_fcn;
00072
00073 gnu_readline (void);
00074
00075 ~gnu_readline (void) { }
00076
00077 void do_set_name (const std::string& n);
00078
00079 std::string do_readline (const std::string& prompt, bool& eof);
00080
00081 void do_set_input_stream (FILE *f);
00082
00083 FILE *do_get_input_stream (void);
00084
00085 void do_set_output_stream (FILE *f);
00086
00087 FILE *do_get_output_stream (void);
00088
00089 int do_terminal_rows (void);
00090
00091 int do_terminal_cols (void);
00092
00093 void do_clear_screen (void);
00094
00095 void do_resize_terminal (void);
00096
00097 std::string newline_chars (void);
00098
00099 void do_restore_terminal_state (void);
00100
00101 void do_blink_matching_paren (bool flag);
00102
00103 void do_set_basic_word_break_characters (const std::string& s);
00104
00105 void do_set_completer_word_break_characters (const std::string& s);
00106
00107 void do_set_basic_quote_characters (const std::string& s);
00108
00109 void do_set_filename_quote_characters (const std::string& s);
00110
00111 void do_set_completer_quote_characters (const std::string& s);
00112
00113 void do_set_completion_append_character (char c);
00114
00115 void do_set_completion_function (completion_fcn f);
00116
00117 void do_set_quoting_function (quoting_fcn f);
00118
00119 void do_set_dequoting_function (dequoting_fcn f);
00120
00121 void do_set_char_is_quoted_function (char_is_quoted_fcn f);
00122
00123 void do_set_user_accept_line_function (user_accept_line_fcn f);
00124
00125 completion_fcn do_get_completion_function (void) const;
00126
00127 quoting_fcn do_get_quoting_function (void) const;
00128
00129 dequoting_fcn do_get_dequoting_function (void) const;
00130
00131 char_is_quoted_fcn do_get_char_is_quoted_function (void) const;
00132
00133 user_accept_line_fcn do_get_user_accept_line_function (void) const;
00134
00135 string_vector
00136 do_generate_filename_completions (const std::string& text);
00137
00138 std::string do_get_line_buffer (void) const;
00139
00140 void do_insert_text (const std::string& text);
00141
00142 void do_newline (void);
00143
00144 void do_accept_line (void);
00145
00146 void do_clear_undo_list (void);
00147
00148 void set_startup_hook (startup_hook_fcn f);
00149
00150 void restore_startup_hook (void);
00151
00152 void set_event_hook (event_hook_fcn f);
00153
00154 void restore_event_hook (void);
00155
00156 void do_restore_event_hook (void);
00157
00158 void do_read_init_file (const std::string& file);
00159
00160 void do_re_read_init_file (void);
00161
00162 bool do_filename_completion_desired (bool);
00163
00164 bool do_filename_quoting_desired (bool);
00165
00166 static int operate_and_get_next (int, int);
00167
00168 static int history_search_backward (int, int);
00169
00170 static int history_search_forward (int, int);
00171
00172 private:
00173
00174 startup_hook_fcn previous_startup_hook;
00175
00176 event_hook_fcn previous_event_hook;
00177
00178 completion_fcn completion_function;
00179
00180 quoting_fcn quoting_function;
00181
00182 dequoting_fcn dequoting_function;
00183
00184 char_is_quoted_fcn char_is_quoted_function;
00185
00186 user_accept_line_fcn user_accept_line_function;
00187
00188 static char *command_generator (const char *text, int state);
00189
00190 static char *command_quoter (char *text, int match_type, char *quote_pointer);
00191 static char *command_dequoter (char *text, int match_type);
00192
00193 static int command_char_is_quoted (char *text, int index);
00194
00195 static int command_accept_line (int count, int key);
00196
00197 static char **command_completer (const char *text, int start, int end);
00198 };
00199
00200 gnu_readline::gnu_readline ()
00201 : command_editor (), previous_startup_hook (0),
00202 previous_event_hook (0), completion_function (0),
00203 quoting_function (0), dequoting_function (0),
00204 char_is_quoted_function (0), user_accept_line_function (0)
00205 {
00206
00207
00208
00209 std::string term = octave_env::getenv ("TERM");
00210
00211 octave_rl_set_terminal_name (term.c_str ());
00212
00213 octave_rl_initialize ();
00214
00215 do_blink_matching_paren (true);
00216
00217
00218
00219 octave_rl_add_defun ("operate-and-get-next",
00220 gnu_readline::operate_and_get_next,
00221 octave_rl_ctrl ('O'));
00222
00223
00224
00225 octave_rl_add_defun ("history-search-backward",
00226 gnu_readline::history_search_backward,
00227 octave_rl_meta ('P'));
00228
00229 octave_rl_add_defun ("history-search-forward",
00230 gnu_readline::history_search_forward,
00231 octave_rl_meta ('N'));
00232 }
00233
00234 void
00235 gnu_readline::do_set_name (const std::string& nm)
00236 {
00237 ::octave_rl_set_name (nm.c_str ());
00238 }
00239
00240 std::string
00241 gnu_readline::do_readline (const std::string& prompt, bool& eof)
00242 {
00243 std::string retval;
00244
00245 eof = false;
00246
00247 char *line = 0;
00248
00249 const char *p = prompt.c_str ();
00250
00251 BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
00252
00253 line = ::octave_rl_readline (p);
00254
00255 END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
00256
00257 if (line)
00258 {
00259 retval = line;
00260
00261 free (line);
00262 }
00263 else
00264 eof = true;
00265
00266 return retval;
00267 }
00268
00269 void
00270 gnu_readline::do_set_input_stream (FILE *f)
00271 {
00272 ::octave_rl_set_input_stream (f);
00273 }
00274
00275 FILE *
00276 gnu_readline::do_get_input_stream (void)
00277 {
00278 return ::octave_rl_get_input_stream ();
00279 }
00280
00281 void
00282 gnu_readline::do_set_output_stream (FILE *f)
00283 {
00284 ::octave_rl_set_output_stream (f);
00285 }
00286
00287 FILE *
00288 gnu_readline::do_get_output_stream (void)
00289 {
00290 return ::octave_rl_get_output_stream ();
00291 }
00292
00293
00294
00295
00296
00297
00298
00299 int
00300 gnu_readline::do_terminal_rows (void)
00301 {
00302 int sh = ::octave_rl_screen_height ();
00303
00304 return sh > 0 ? sh : 24;
00305 }
00306
00307 int
00308 gnu_readline::do_terminal_cols (void)
00309 {
00310 int sw = ::octave_rl_screen_width ();
00311
00312 return sw > 0 ? sw : 80;
00313 }
00314
00315 void
00316 gnu_readline::do_clear_screen (void)
00317 {
00318 ::octave_rl_clear_screen ();
00319 }
00320
00321 void
00322 gnu_readline::do_resize_terminal (void)
00323 {
00324 ::octave_rl_resize_terminal ();
00325 }
00326
00327 std::string
00328 gnu_readline::newline_chars (void)
00329 {
00330 return "\r\n";
00331 }
00332
00333 void
00334 gnu_readline::do_restore_terminal_state (void)
00335 {
00336 ::octave_rl_restore_terminal_state ();
00337 }
00338
00339 void
00340 gnu_readline::do_blink_matching_paren (bool flag)
00341 {
00342 ::octave_rl_enable_paren_matching (flag ? 1 : 0);
00343 }
00344
00345 void
00346 gnu_readline::do_set_basic_word_break_characters (const std::string& s)
00347 {
00348 ::octave_rl_set_basic_word_break_characters (s.c_str ());
00349 }
00350
00351 void
00352 gnu_readline::do_set_completer_word_break_characters (const std::string& s)
00353 {
00354 ::octave_rl_set_completer_word_break_characters (s.c_str ());
00355 }
00356
00357 void
00358 gnu_readline::do_set_basic_quote_characters (const std::string& s)
00359 {
00360 ::octave_rl_set_basic_quote_characters (s.c_str ());
00361 }
00362
00363 void
00364 gnu_readline::do_set_filename_quote_characters (const std::string& s)
00365 {
00366 ::octave_rl_set_filename_quote_characters (s.c_str ());
00367 }
00368
00369 void
00370 gnu_readline::do_set_completer_quote_characters (const std::string& s)
00371 {
00372 ::octave_rl_set_completer_quote_characters (s.c_str ());
00373 }
00374
00375 void
00376 gnu_readline::do_set_completion_append_character (char c)
00377 {
00378 ::octave_rl_set_completion_append_character (c);
00379 }
00380
00381 void
00382 gnu_readline::do_set_completion_function (completion_fcn f)
00383 {
00384 completion_function = f;
00385
00386 rl_attempted_completion_fcn_ptr fp
00387 = f ? gnu_readline::command_completer : 0;
00388
00389 ::octave_rl_set_completion_function (fp);
00390 }
00391
00392 void
00393 gnu_readline::do_set_quoting_function (quoting_fcn f)
00394 {
00395 quoting_function = f;
00396
00397 rl_quoting_fcn_ptr fp
00398 = f ? gnu_readline::command_quoter : 0;
00399
00400 ::octave_rl_set_quoting_function (fp);
00401 }
00402
00403 void
00404 gnu_readline::do_set_dequoting_function (dequoting_fcn f)
00405 {
00406 dequoting_function = f;
00407
00408 rl_dequoting_fcn_ptr fp
00409 = f ? gnu_readline::command_dequoter : 0;
00410
00411 ::octave_rl_set_dequoting_function (fp);
00412 }
00413
00414 void
00415 gnu_readline::do_set_char_is_quoted_function (char_is_quoted_fcn f)
00416 {
00417 char_is_quoted_function = f;
00418
00419 rl_char_is_quoted_fcn_ptr fp
00420 = f ? gnu_readline::command_char_is_quoted : 0;
00421
00422 ::octave_rl_set_char_is_quoted_function (fp);
00423 }
00424
00425 void
00426 gnu_readline::do_set_user_accept_line_function (user_accept_line_fcn f)
00427 {
00428 user_accept_line_function = f;
00429
00430 if (f)
00431 octave_rl_add_defun ("accept-line", gnu_readline::command_accept_line,
00432 ::octave_rl_ctrl ('M'));
00433 else
00434 octave_rl_add_defun ("accept-line", ::octave_rl_newline,
00435 ::octave_rl_ctrl ('M'));
00436 }
00437
00438 gnu_readline::completion_fcn
00439 gnu_readline::do_get_completion_function (void) const
00440 {
00441 return completion_function;
00442 }
00443
00444 gnu_readline::quoting_fcn
00445 gnu_readline::do_get_quoting_function (void) const
00446 {
00447 return quoting_function;
00448 }
00449
00450 gnu_readline::dequoting_fcn
00451 gnu_readline::do_get_dequoting_function (void) const
00452 {
00453 return dequoting_function;
00454 }
00455
00456 gnu_readline::char_is_quoted_fcn
00457 gnu_readline::do_get_char_is_quoted_function (void) const
00458 {
00459 return char_is_quoted_function;
00460 }
00461
00462 gnu_readline::user_accept_line_fcn
00463 gnu_readline::do_get_user_accept_line_function (void) const
00464 {
00465 return user_accept_line_function;
00466 }
00467
00468 string_vector
00469 gnu_readline::do_generate_filename_completions (const std::string& text)
00470 {
00471 string_vector retval;
00472
00473 int n = 0;
00474 int count = 0;
00475
00476 char *fn = 0;
00477
00478 while (1)
00479 {
00480 fn = ::octave_rl_filename_completion_function (text.c_str (), count);
00481
00482 if (fn)
00483 {
00484 if (count == n)
00485 {
00486
00487
00488
00489
00490 n += 100;
00491 retval.resize (n);
00492 }
00493
00494 retval[count++] = fn;
00495
00496 free (fn);
00497 }
00498 else
00499 break;
00500 }
00501
00502 retval.resize (count);
00503
00504 return retval;
00505 }
00506
00507 std::string
00508 gnu_readline::do_get_line_buffer (void) const
00509 {
00510 return ::octave_rl_line_buffer ();
00511 }
00512
00513 void
00514 gnu_readline::do_insert_text (const std::string& text)
00515 {
00516 ::octave_rl_insert_text (text.c_str ());
00517 }
00518
00519 void
00520 gnu_readline::do_newline (void)
00521 {
00522 ::octave_rl_newline (1, '\n');
00523 }
00524
00525 void
00526 gnu_readline::do_accept_line (void)
00527 {
00528 command_accept_line (1, '\n');
00529 }
00530
00531 void
00532 gnu_readline::do_clear_undo_list ()
00533 {
00534 ::octave_rl_clear_undo_list ();
00535 }
00536
00537 void
00538 gnu_readline::set_startup_hook (startup_hook_fcn f)
00539 {
00540 previous_startup_hook = ::octave_rl_get_startup_hook ();
00541
00542 if (f != previous_startup_hook)
00543 ::octave_rl_set_startup_hook (f);
00544 }
00545
00546 void
00547 gnu_readline::restore_startup_hook (void)
00548 {
00549 ::octave_rl_set_startup_hook (previous_startup_hook);
00550 }
00551
00552 void
00553 gnu_readline::set_event_hook (event_hook_fcn f)
00554 {
00555 previous_event_hook = octave_rl_get_event_hook ();
00556
00557 ::octave_rl_set_event_hook (f);
00558 }
00559
00560 void
00561 gnu_readline::restore_event_hook (void)
00562 {
00563 ::octave_rl_set_event_hook (previous_event_hook);
00564 }
00565
00566 void
00567 gnu_readline::do_read_init_file (const std::string& file)
00568 {
00569 ::octave_rl_read_init_file (file.c_str ());
00570 }
00571
00572 void
00573 gnu_readline::do_re_read_init_file (void)
00574 {
00575 ::octave_rl_re_read_init_file ();
00576 }
00577
00578 bool
00579 gnu_readline::do_filename_completion_desired (bool arg)
00580 {
00581 return ::octave_rl_filename_completion_desired (arg);
00582 }
00583
00584 bool
00585 gnu_readline::do_filename_quoting_desired (bool arg)
00586 {
00587 return ::octave_rl_filename_quoting_desired (arg);
00588 }
00589
00590 int
00591 gnu_readline::operate_and_get_next (int , int )
00592 {
00593
00594
00595 command_editor::accept_line ();
00596
00597
00598
00599 int x_where = command_history::where ();
00600
00601 int x_length = command_history::length ();
00602
00603 if ((command_history::is_stifled ()
00604 && (x_length >= command_history::max_input_history ()))
00605 || (x_where >= x_length - 1))
00606 command_history::set_mark (x_where);
00607 else
00608 command_history::set_mark (x_where + 1);
00609
00610 command_editor::add_startup_hook (command_history::goto_mark);
00611
00612 return 0;
00613 }
00614
00615 int
00616 gnu_readline::history_search_backward (int count, int c)
00617 {
00618 return octave_rl_history_search_backward (count, c);
00619 }
00620
00621 int
00622 gnu_readline::history_search_forward (int count, int c)
00623 {
00624 return octave_rl_history_search_forward (count, c);
00625 }
00626
00627 char *
00628 gnu_readline::command_generator (const char *text, int state)
00629 {
00630 char *retval = 0;
00631
00632 completion_fcn f = command_editor::get_completion_function ();
00633
00634 std::string tmp = f (text, state);
00635
00636 size_t len = tmp.length ();
00637
00638 if (len > 0)
00639 {
00640 retval = static_cast<char *> (gnulib::malloc (len+1));
00641
00642 strcpy (retval, tmp.c_str ());
00643 }
00644
00645 return retval;
00646 }
00647
00648 char *
00649 gnu_readline::command_quoter (char *text, int matches, char *qcp)
00650 {
00651 char *retval = 0;
00652
00653 quoting_fcn f = command_editor::get_quoting_function ();
00654
00655 std::string tmp = f (text, matches, *qcp);
00656
00657 size_t len = tmp.length ();
00658
00659 if (len > 0)
00660 {
00661 retval = static_cast<char *> (gnulib::malloc (len+1));
00662
00663 strcpy (retval, tmp.c_str ());
00664 }
00665
00666 return retval;
00667 }
00668
00669 char *
00670 gnu_readline::command_dequoter (char *text, int quote)
00671 {
00672 char *retval = 0;
00673
00674 dequoting_fcn f = command_editor::get_dequoting_function ();
00675
00676 std::string tmp = f (text, quote);
00677
00678 size_t len = tmp.length ();
00679
00680 if (len > 0)
00681 {
00682 retval = static_cast<char *> (gnulib::malloc (len+1));
00683
00684 strcpy (retval, tmp.c_str ());
00685 }
00686
00687 return retval;
00688 }
00689
00690 int
00691 gnu_readline::command_char_is_quoted (char *text, int quote)
00692 {
00693 char_is_quoted_fcn f = command_editor::get_char_is_quoted_function ();
00694
00695 return f (text, quote);
00696 }
00697
00698 int
00699 gnu_readline::command_accept_line (int count, int key)
00700 {
00701 user_accept_line_fcn f = command_editor::get_user_accept_line_function ();
00702
00703 if (f)
00704 f (::octave_rl_line_buffer ());
00705
00706 ::octave_rl_redisplay ();
00707
00708 return ::octave_rl_newline (count, key);
00709 }
00710
00711 char **
00712 gnu_readline::command_completer (const char *text, int, int)
00713 {
00714 char **matches = 0;
00715 matches
00716 = ::octave_rl_completion_matches (text, gnu_readline::command_generator);
00717 return matches;
00718 }
00719
00720 #endif
00721
00722 class
00723 default_command_editor : public command_editor
00724 {
00725 public:
00726
00727 default_command_editor (void)
00728 : command_editor (), input_stream (stdin), output_stream (stdout) { }
00729
00730 ~default_command_editor (void) { }
00731
00732 std::string do_readline (const std::string& prompt, bool& eof);
00733
00734 void do_set_input_stream (FILE *f);
00735
00736 FILE *do_get_input_stream (void);
00737
00738 void do_set_output_stream (FILE *f);
00739
00740 FILE *do_get_output_stream (void);
00741
00742 string_vector do_generate_filename_completions (const std::string& text);
00743
00744 std::string do_get_line_buffer (void) const;
00745
00746 void do_insert_text (const std::string&);
00747
00748 void do_newline (void);
00749
00750 void do_accept_line (void);
00751
00752 private:
00753
00754 FILE *input_stream;
00755
00756 FILE *output_stream;
00757
00758
00759
00760 default_command_editor (const default_command_editor&);
00761
00762 default_command_editor& operator = (const default_command_editor&);
00763 };
00764
00765 std::string
00766 default_command_editor::do_readline (const std::string& prompt, bool& eof)
00767 {
00768 gnulib::fputs (prompt.c_str (), output_stream);
00769 gnulib::fflush (output_stream);
00770
00771 return octave_fgetl (input_stream, eof);
00772 }
00773
00774 void
00775 default_command_editor::do_set_input_stream (FILE *f)
00776 {
00777 input_stream = f;
00778 }
00779
00780 FILE *
00781 default_command_editor::do_get_input_stream (void)
00782 {
00783 return input_stream;
00784 }
00785
00786 void
00787 default_command_editor::do_set_output_stream (FILE *f)
00788 {
00789 output_stream = f;
00790 }
00791
00792 FILE *
00793 default_command_editor::do_get_output_stream (void)
00794 {
00795 return output_stream;
00796 }
00797
00798 string_vector
00799 default_command_editor::do_generate_filename_completions (const std::string&)
00800 {
00801
00802 return string_vector ();
00803 }
00804
00805 std::string
00806 default_command_editor::do_get_line_buffer (void) const
00807 {
00808 return "";
00809 }
00810
00811 void
00812 default_command_editor::do_insert_text (const std::string&)
00813 {
00814
00815 }
00816
00817 void
00818 default_command_editor::do_newline (void)
00819 {
00820
00821 }
00822
00823 void
00824 default_command_editor::do_accept_line (void)
00825 {
00826
00827 }
00828
00829 bool
00830 command_editor::instance_ok (void)
00831 {
00832 bool retval = true;
00833
00834 if (! instance)
00835 {
00836 make_command_editor ();
00837
00838 if (instance)
00839 singleton_cleanup_list::add (cleanup_instance);
00840 }
00841
00842 if (! instance)
00843 {
00844 current_liboctave_error_handler
00845 ("unable to create command history object!");
00846
00847 retval = false;
00848 }
00849
00850 return retval;
00851 }
00852
00853 void
00854 command_editor::make_command_editor (void)
00855 {
00856 #if defined (USE_READLINE)
00857 instance = new gnu_readline ();
00858 #else
00859 instance = new default_command_editor ();
00860 #endif
00861 }
00862
00863 void
00864 command_editor::force_default_editor (void)
00865 {
00866 delete instance;
00867 instance = new default_command_editor ();
00868 }
00869
00870 int
00871 command_editor::startup_handler (void)
00872 {
00873 for (startup_hook_set_iterator p = startup_hook_set.begin ();
00874 p != startup_hook_set.end (); p++)
00875 {
00876 startup_hook_fcn f = *p;
00877
00878 if (f)
00879 f ();
00880 }
00881
00882 return 0;
00883 }
00884
00885 int
00886 command_editor::event_handler (void)
00887 {
00888 event_hook_lock.lock ();
00889
00890 std::set<event_hook_fcn> hook_set (event_hook_set);
00891
00892 event_hook_lock.unlock ();
00893
00894 for (event_hook_set_iterator p = hook_set.begin ();
00895 p != hook_set.end (); p++)
00896 {
00897 event_hook_fcn f = *p;
00898
00899 if (f)
00900 f ();
00901 }
00902
00903 return 0;
00904 }
00905
00906 void
00907 command_editor::set_name (const std::string& n)
00908 {
00909 if (instance_ok ())
00910 instance->do_set_name (n);
00911 }
00912
00913 std::string
00914 command_editor::readline (const std::string& prompt)
00915 {
00916 bool eof;
00917
00918 return readline (prompt, eof);
00919 }
00920
00921 std::string
00922 command_editor::readline (const std::string& prompt, bool& eof)
00923 {
00924 return (instance_ok ())
00925 ? instance->do_readline (prompt, eof) : std::string ();
00926 }
00927
00928 void
00929 command_editor::set_input_stream (FILE *f)
00930 {
00931 if (instance_ok ())
00932 instance->do_set_input_stream (f);
00933 }
00934
00935 FILE *
00936 command_editor::get_input_stream (void)
00937 {
00938 return (instance_ok ())
00939 ? instance->do_get_input_stream () : 0;
00940 }
00941
00942 void
00943 command_editor::set_output_stream (FILE *f)
00944 {
00945 if (instance_ok ())
00946 instance->do_set_output_stream (f);
00947 }
00948
00949 FILE *
00950 command_editor::get_output_stream (void)
00951 {
00952 return (instance_ok ())
00953 ? instance->do_get_output_stream () : 0;
00954 }
00955
00956 int
00957 command_editor::terminal_rows (void)
00958 {
00959 return (instance_ok ())
00960 ? instance->do_terminal_rows () : -1;
00961 }
00962
00963 int
00964 command_editor::terminal_cols (void)
00965 {
00966 return (instance_ok ())
00967 ? instance->do_terminal_cols () : -1;
00968 }
00969
00970 void
00971 command_editor::clear_screen (void)
00972 {
00973 if (instance_ok ())
00974 instance->do_clear_screen ();
00975 }
00976
00977 void
00978 command_editor::resize_terminal (void)
00979 {
00980 if (instance_ok ())
00981 instance->do_resize_terminal ();
00982 }
00983
00984 std::string
00985 command_editor::decode_prompt_string (const std::string& s)
00986 {
00987 return (instance_ok ())
00988 ? instance->do_decode_prompt_string (s) : std::string ();
00989 }
00990
00991 int
00992 command_editor::current_command_number (void)
00993 {
00994 return (instance_ok ())
00995 ? instance->command_number : 0;
00996 }
00997
00998 void
00999 command_editor::reset_current_command_number (int n)
01000 {
01001 if (instance_ok ())
01002 instance->command_number = n;
01003 }
01004
01005 void
01006 command_editor::increment_current_command_number (void)
01007 {
01008 if (instance_ok ())
01009 instance->command_number++;
01010 }
01011
01012 void
01013 command_editor::restore_terminal_state (void)
01014 {
01015 if (instance_ok ())
01016 instance->do_restore_terminal_state ();
01017 }
01018
01019 void
01020 command_editor::blink_matching_paren (bool flag)
01021 {
01022 if (instance_ok ())
01023 instance->do_blink_matching_paren (flag);
01024 }
01025
01026 void
01027 command_editor::set_basic_word_break_characters (const std::string& s)
01028 {
01029 if (instance_ok ())
01030 instance->do_set_basic_word_break_characters (s);
01031 }
01032
01033 void
01034 command_editor::set_completer_word_break_characters (const std::string& s)
01035 {
01036 if (instance_ok ())
01037 instance->do_set_completer_word_break_characters (s);
01038 }
01039
01040 void
01041 command_editor::set_basic_quote_characters (const std::string& s)
01042 {
01043 if (instance_ok ())
01044 instance->do_set_basic_quote_characters (s);
01045 }
01046
01047 void
01048 command_editor::set_filename_quote_characters (const std::string& s)
01049 {
01050 if (instance_ok ())
01051 instance->do_set_filename_quote_characters (s);
01052 }
01053
01054 void
01055 command_editor::set_completer_quote_characters (const std::string& s)
01056 {
01057 if (instance_ok ())
01058 instance->do_set_completer_quote_characters (s);
01059 }
01060
01061 void
01062 command_editor::set_completion_append_character (char c)
01063 {
01064 if (instance_ok ())
01065 instance->do_set_completion_append_character (c);
01066 }
01067
01068 void
01069 command_editor::set_completion_function (completion_fcn f)
01070 {
01071 if (instance_ok ())
01072 instance->do_set_completion_function (f);
01073 }
01074
01075 void
01076 command_editor::set_quoting_function (quoting_fcn f)
01077 {
01078 if (instance_ok ())
01079 instance->do_set_quoting_function (f);
01080 }
01081
01082 void
01083 command_editor::set_dequoting_function (dequoting_fcn f)
01084 {
01085 if (instance_ok ())
01086 instance->do_set_dequoting_function (f);
01087 }
01088
01089 void
01090 command_editor::set_char_is_quoted_function (char_is_quoted_fcn f)
01091 {
01092 if (instance_ok ())
01093 instance->do_set_char_is_quoted_function (f);
01094 }
01095
01096 void
01097 command_editor::set_user_accept_line_function (user_accept_line_fcn f)
01098 {
01099 if (instance_ok ())
01100 instance->do_set_user_accept_line_function (f);
01101 }
01102
01103 command_editor::completion_fcn
01104 command_editor::get_completion_function (void)
01105 {
01106 return (instance_ok ())
01107 ? instance->do_get_completion_function () : 0;
01108 }
01109
01110 command_editor::quoting_fcn
01111 command_editor::get_quoting_function (void)
01112 {
01113 return (instance_ok ())
01114 ? instance->do_get_quoting_function () : 0;
01115 }
01116
01117 command_editor::dequoting_fcn
01118 command_editor::get_dequoting_function (void)
01119 {
01120 return (instance_ok ())
01121 ? instance->do_get_dequoting_function () : 0;
01122 }
01123
01124 command_editor::char_is_quoted_fcn
01125 command_editor::get_char_is_quoted_function (void)
01126 {
01127 return (instance_ok ())
01128 ? instance->do_get_char_is_quoted_function () : 0;
01129 }
01130
01131 command_editor::user_accept_line_fcn
01132 command_editor::get_user_accept_line_function (void)
01133 {
01134 return (instance_ok ())
01135 ? instance->do_get_user_accept_line_function () : 0;
01136 }
01137
01138 string_vector
01139 command_editor::generate_filename_completions (const std::string& text)
01140 {
01141 return (instance_ok ())
01142 ? instance->do_generate_filename_completions (text) : string_vector ();
01143 }
01144
01145 std::string
01146 command_editor::get_line_buffer (void)
01147 {
01148 return (instance_ok ()) ? instance->do_get_line_buffer () : "";
01149 }
01150
01151 void
01152 command_editor::insert_text (const std::string& text)
01153 {
01154 if (instance_ok ())
01155 instance->do_insert_text (text);
01156 }
01157
01158 void
01159 command_editor::newline (void)
01160 {
01161 if (instance_ok ())
01162 instance->do_newline ();
01163 }
01164
01165 void
01166 command_editor::accept_line (void)
01167 {
01168 if (instance_ok ())
01169 instance->do_accept_line ();
01170 }
01171
01172 void
01173 command_editor::clear_undo_list (void)
01174 {
01175 if (instance_ok ())
01176 instance->do_clear_undo_list ();
01177 }
01178
01179 void
01180 command_editor::add_startup_hook (startup_hook_fcn f)
01181 {
01182 if (instance_ok ())
01183 {
01184 startup_hook_set.insert (f);
01185
01186 instance->set_startup_hook (startup_handler);
01187 }
01188 }
01189
01190 void
01191 command_editor::remove_startup_hook (startup_hook_fcn f)
01192 {
01193 if (instance_ok ())
01194 {
01195 startup_hook_set_iterator p = startup_hook_set.find (f);
01196
01197 if (p != startup_hook_set.end ())
01198 startup_hook_set.erase (p);
01199
01200 if (startup_hook_set.empty ())
01201 instance->restore_startup_hook ();
01202 }
01203 }
01204
01205 void
01206 command_editor::add_event_hook (event_hook_fcn f)
01207 {
01208 octave_autolock guard (event_hook_lock);
01209
01210 if (instance_ok ())
01211 {
01212 event_hook_set.insert (f);
01213
01214 instance->set_event_hook (event_handler);
01215 }
01216 }
01217
01218 void
01219 command_editor::remove_event_hook (event_hook_fcn f)
01220 {
01221 octave_autolock guard (event_hook_lock);
01222
01223 if (instance_ok ())
01224 {
01225 event_hook_set_iterator p = event_hook_set.find (f);
01226
01227 if (p != event_hook_set.end ())
01228 event_hook_set.erase (p);
01229
01230 if (event_hook_set.empty ())
01231 instance->restore_event_hook ();
01232 }
01233 }
01234
01235 void
01236 command_editor::run_event_hooks (void)
01237 {
01238 event_handler ();
01239 }
01240
01241 void
01242 command_editor::read_init_file (const std::string& file_arg)
01243 {
01244 if (instance_ok ())
01245 {
01246 std::string file = file_ops::tilde_expand (file_arg);
01247
01248 instance->do_read_init_file (file);
01249 }
01250 }
01251
01252 void
01253 command_editor::re_read_init_file (void)
01254 {
01255 if (instance_ok ())
01256 instance->do_re_read_init_file ();
01257 }
01258
01259 bool
01260 command_editor::filename_completion_desired (bool arg)
01261 {
01262 return (instance_ok ())
01263 ? instance->do_filename_completion_desired (arg) : false;
01264 }
01265
01266 bool
01267 command_editor::filename_quoting_desired (bool arg)
01268 {
01269 return (instance_ok ())
01270 ? instance->do_filename_quoting_desired (arg) : false;
01271 }
01272
01273
01274
01275
01276
01277
01278
01279
01280
01281
01282
01283
01284
01285
01286
01287
01288
01289
01290
01291
01292
01293
01294
01295
01296
01297
01298
01299 std::string
01300 command_editor::do_decode_prompt_string (const std::string& s)
01301 {
01302 std::string result;
01303 std::string temp;
01304 size_t i = 0;
01305 size_t slen = s.length ();
01306 int c;
01307
01308 while (i < slen)
01309 {
01310 c = s[i];
01311
01312 i++;
01313
01314 if (c == '\\')
01315 {
01316 c = s[i];
01317
01318 switch (c)
01319 {
01320 case '0':
01321 case '1':
01322 case '2':
01323 case '3':
01324 case '4':
01325 case '5':
01326 case '6':
01327 case '7':
01328
01329 {
01330 int n = read_octal (s.substr (i, 3));
01331
01332 temp = "\\";
01333
01334 if (n != -1)
01335 {
01336 i += 3;
01337 temp[0] = n;
01338 }
01339
01340 c = 0;
01341 goto add_string;
01342 }
01343
01344 case 'a':
01345 {
01346 temp = '\a';
01347
01348 goto add_string;
01349 }
01350
01351 case 'e':
01352 {
01353 temp = '\033';
01354
01355 goto add_string;
01356 }
01357
01358 case 'r':
01359 {
01360 temp = '\r';
01361
01362 goto add_string;
01363 }
01364
01365 case 'd':
01366 case 't':
01367 case 'T':
01368 case '@':
01369 case 'A':
01370
01371 {
01372 octave_localtime now;
01373
01374 if (c == 'd')
01375 temp = now.strftime ("%a %b %d");
01376 else if (c == 't')
01377 temp = now.strftime ("%H:%M:%S");
01378 else if (c == 'T')
01379 temp = now.strftime ("%I:%M:%S");
01380 else if (c == '@')
01381 temp = now.strftime ("%I:%M %p");
01382 else if (c == 'A')
01383 temp = now.strftime ("%H:%M");
01384
01385 goto add_string;
01386 }
01387
01388 case 'n':
01389 {
01390 temp = newline_chars ();
01391
01392 goto add_string;
01393 }
01394
01395 case 's':
01396 {
01397 temp = octave_env::get_program_name ();
01398 temp = octave_env::base_pathname (temp);
01399
01400 goto add_string;
01401 }
01402
01403 case 'w':
01404 case 'W':
01405 {
01406 temp = octave_env::get_current_directory ();
01407
01408 std::string home_dir = octave_env::get_home_directory ();
01409
01410 if (c == 'W' && (home_dir.empty () || temp != home_dir))
01411 {
01412 if (temp != "/" && temp != "//")
01413 {
01414 size_t pos = temp.rfind ('/');
01415
01416 if (pos != std::string::npos && pos != 0)
01417 temp = temp.substr (pos + 1);
01418 }
01419 }
01420 else
01421 temp = octave_env::polite_directory_format (temp);
01422
01423 goto add_string;
01424 }
01425
01426 case 'u':
01427 {
01428 temp = octave_env::get_user_name ();
01429
01430 goto add_string;
01431 }
01432
01433 case 'H':
01434 {
01435 temp = octave_env::get_host_name ();
01436
01437 goto add_string;
01438 }
01439
01440 case 'h':
01441 {
01442 temp = octave_env::get_host_name ();
01443
01444 size_t pos = temp.find ('.');
01445
01446 if (pos != std::string::npos)
01447 temp.resize (pos);
01448
01449 goto add_string;
01450 }
01451
01452 case '#':
01453 {
01454 char number_buffer[128];
01455 sprintf (number_buffer, "%d", command_number);
01456 temp = number_buffer;
01457
01458 goto add_string;
01459 }
01460
01461 case '!':
01462 {
01463 char number_buffer[128];
01464 int num = command_history::current_number ();
01465 if (num > 0)
01466 sprintf (number_buffer, "%d", num);
01467 else
01468 strcpy (number_buffer, "!");
01469 temp = number_buffer;
01470
01471 goto add_string;
01472 }
01473
01474 case '$':
01475 {
01476 #if defined (HAVE_GETEUID)
01477 temp = (::geteuid () == 0 ? "#" : "$");
01478 #else
01479 temp = "$";
01480 #endif
01481
01482 goto add_string;
01483 }
01484
01485 #if defined (USE_READLINE)
01486 case '[':
01487 case ']':
01488 {
01489 temp.resize (1);
01490
01491 temp[0] = ((c == '[')
01492 ? ::octave_rl_prompt_start_ignore ()
01493 : ::octave_rl_prompt_end_ignore ());
01494
01495 goto add_string;
01496 }
01497 #endif
01498
01499 case '\\':
01500 {
01501 temp = "\\";
01502
01503 goto add_string;
01504 }
01505
01506 default:
01507 {
01508 temp = "\\ ";
01509 temp[1] = c;
01510
01511 goto add_string;
01512 }
01513
01514 add_string:
01515 {
01516 if (c)
01517 i++;
01518
01519 result.append (temp);
01520
01521 break;
01522 }
01523 }
01524 }
01525 else
01526 result += c;
01527 }
01528
01529 return result;
01530 }
01531
01532
01533
01534
01535 int
01536 command_editor::read_octal (const std::string& s)
01537 {
01538 int result = 0;
01539 int digits = 0;
01540
01541 size_t i = 0;
01542 size_t slen = s.length ();
01543
01544 while (i < slen && s[i] >= '0' && s[i] < '8')
01545 {
01546 digits++;
01547 result = (result * 8) + s[i] - '0';
01548 i++;
01549 }
01550
01551 if (! digits || result > 0777 || i < slen)
01552 result = -1;
01553
01554 return result;
01555 }
01556
01557 void
01558 command_editor::error (int err_num)
01559 {
01560 current_liboctave_error_handler ("%s", gnulib::strerror (err_num));
01561 }
01562
01563 void
01564 command_editor::error (const std::string& s)
01565 {
01566 current_liboctave_error_handler ("%s", s.c_str ());
01567 }