Mercurial > hg > octave-nkf
annotate liboctave/cmd-edit.cc @ 12011:67ad3b58b99a release-3-2-x
improve error handling
author | Jaroslav Hajek <highegg@gmail.com> |
---|---|
date | Wed, 24 Jun 2009 07:31:32 +0200 |
parents | bfa0fc8559b5 |
children | 3cee58bf4acf |
rev | line source |
---|---|
2926 | 1 /* |
2 | |
7017 | 3 Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2005, |
8920 | 4 2006, 2007, 2008, 2009 John W. Eaton |
2926 | 5 |
6 This file is part of Octave. | |
7 | |
8 Octave is free software; you can redistribute it and/or modify it | |
9 under the terms of the GNU General Public License as published by the | |
7016 | 10 Free Software Foundation; either version 3 of the License, or (at your |
11 option) any later version. | |
2926 | 12 |
13 Octave is distributed in the hope that it will be useful, but WITHOUT | |
14 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
16 for more details. | |
17 | |
18 You should have received a copy of the GNU General Public License | |
7016 | 19 along with Octave; see the file COPYING. If not, see |
20 <http://www.gnu.org/licenses/>. | |
2926 | 21 |
22 */ | |
23 | |
24 #ifdef HAVE_CONFIG_H | |
25 #include <config.h> | |
26 #endif | |
27 | |
3225 | 28 #include <cstdlib> |
2926 | 29 #include <cstring> |
30 | |
31 #include <string> | |
32 | |
33 #ifdef HAVE_UNISTD_H | |
34 #ifdef HAVE_SYS_TYPES_H | |
35 #include <sys/types.h> | |
36 #endif | |
37 #include <unistd.h> | |
38 #endif | |
39 | |
5247 | 40 #include "quit.h" |
41 | |
2926 | 42 #include "cmd-edit.h" |
43 #include "cmd-hist.h" | |
5872 | 44 #include "file-ops.h" |
2926 | 45 #include "lo-error.h" |
46 #include "lo-utils.h" | |
47 #include "oct-env.h" | |
7936
78400fde223e
Support for backend-to-octave event management
John W. Eaton <jwe@octave.org>
parents:
7758
diff
changeset
|
48 #include "oct-mutex.h" |
3260 | 49 #include "oct-time.h" |
2926 | 50 |
51 command_editor *command_editor::instance = 0; | |
52 | |
6913 | 53 std::set<command_editor::startup_hook_fcn> command_editor::startup_hook_set; |
54 | |
55 std::set<command_editor::event_hook_fcn> command_editor::event_hook_set; | |
56 | |
7936
78400fde223e
Support for backend-to-octave event management
John W. Eaton <jwe@octave.org>
parents:
7758
diff
changeset
|
57 static octave_mutex event_hook_lock; |
78400fde223e
Support for backend-to-octave event management
John W. Eaton <jwe@octave.org>
parents:
7758
diff
changeset
|
58 |
2926 | 59 #if defined (USE_READLINE) |
60 | |
61 #include <cstdio> | |
62 #include <cstdlib> | |
63 | |
3519 | 64 #include "oct-rl-edit.h" |
2926 | 65 |
66 class | |
67 gnu_readline : public command_editor | |
68 { | |
69 public: | |
70 | |
3519 | 71 typedef command_editor::startup_hook_fcn startup_hook_fcn; |
72 | |
6913 | 73 typedef command_editor::event_hook_fcn event_hook_fcn; |
2926 | 74 |
2941 | 75 typedef command_editor::completion_fcn completion_fcn; |
76 | |
2926 | 77 gnu_readline (void); |
78 | |
79 ~gnu_readline (void) { } | |
80 | |
3504 | 81 void do_set_name (const std::string& n); |
2926 | 82 |
3504 | 83 std::string do_readline (const std::string& prompt, bool& eof); |
2926 | 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 int do_terminal_rows (void); | |
94 | |
95 int do_terminal_cols (void); | |
96 | |
97 void do_clear_screen (void); | |
98 | |
3281 | 99 void do_resize_terminal (void); |
100 | |
3504 | 101 std::string newline_chars (void); |
2926 | 102 |
103 void do_restore_terminal_state (void); | |
104 | |
105 void do_blink_matching_paren (bool flag); | |
106 | |
3933 | 107 void do_set_basic_word_break_characters (const std::string& s); |
108 | |
109 void do_set_completer_word_break_characters (const std::string& s); | |
110 | |
3504 | 111 void do_set_basic_quote_characters (const std::string& s); |
2926 | 112 |
6979 | 113 void do_set_filename_quote_characters (const std::string& s); |
114 | |
115 void do_set_completer_quote_characters (const std::string& s); | |
116 | |
2926 | 117 void do_set_completion_append_character (char c); |
118 | |
2941 | 119 void do_set_completion_function (completion_fcn f); |
120 | |
6979 | 121 void do_set_quoting_function (quoting_fcn f); |
122 | |
123 void do_set_dequoting_function (dequoting_fcn f); | |
124 | |
125 void do_set_char_is_quoted_function (char_is_quoted_fcn f); | |
126 | |
127 void do_set_user_accept_line_function (user_accept_line_fcn f); | |
128 | |
2941 | 129 completion_fcn do_get_completion_function (void) const; |
2926 | 130 |
6979 | 131 quoting_fcn do_get_quoting_function (void) const; |
132 | |
133 dequoting_fcn do_get_dequoting_function (void) const; | |
134 | |
135 char_is_quoted_fcn do_get_char_is_quoted_function (void) const; | |
136 | |
137 user_accept_line_fcn do_get_user_accept_line_function (void) const; | |
138 | |
4604 | 139 string_vector |
140 do_generate_filename_completions (const std::string& text); | |
141 | |
3504 | 142 void do_insert_text (const std::string& text); |
2926 | 143 |
144 void do_newline (void); | |
145 | |
6979 | 146 void do_accept_line (void); |
147 | |
2926 | 148 void do_clear_undo_list (void); |
149 | |
6913 | 150 void set_startup_hook (startup_hook_fcn f); |
151 | |
152 void restore_startup_hook (void); | |
2926 | 153 |
6913 | 154 void set_event_hook (event_hook_fcn f); |
2926 | 155 |
6913 | 156 void restore_event_hook (void); |
3215 | 157 |
158 void do_restore_event_hook (void); | |
159 | |
3504 | 160 void do_read_init_file (const std::string& file); |
3189 | 161 |
7758
8e14a01ffe9f
input.cc (Fre_read_readline_init_file): new function
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
162 void do_re_read_init_file (void); |
8e14a01ffe9f
input.cc (Fre_read_readline_init_file): new function
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
163 |
4143 | 164 bool do_filename_completion_desired (bool); |
165 | |
6979 | 166 bool do_filename_quoting_desired (bool); |
167 | |
3519 | 168 static int operate_and_get_next (int, int); |
2926 | 169 |
3951 | 170 static int history_search_backward (int, int); |
171 | |
172 static int history_search_forward (int, int); | |
173 | |
2926 | 174 private: |
175 | |
3519 | 176 startup_hook_fcn previous_startup_hook; |
2926 | 177 |
3519 | 178 event_hook_fcn previous_event_hook; |
3215 | 179 |
2941 | 180 completion_fcn completion_function; |
181 | |
6979 | 182 quoting_fcn quoting_function; |
183 | |
184 dequoting_fcn dequoting_function; | |
185 | |
186 char_is_quoted_fcn char_is_quoted_function; | |
187 | |
188 user_accept_line_fcn user_accept_line_function; | |
189 | |
2941 | 190 static char *command_generator (const char *text, int state); |
191 | |
6979 | 192 static char *command_quoter (char *text, int match_type, char *quote_pointer); |
193 static char *command_dequoter (char *text, int match_type); | |
194 | |
195 static int command_char_is_quoted (char *text, int index); | |
196 | |
197 static int command_accept_line (int count, int key); | |
198 | |
3519 | 199 static char **command_completer (const char *text, int start, int end); |
2926 | 200 }; |
201 | |
202 gnu_readline::gnu_readline () | |
3215 | 203 : command_editor (), previous_startup_hook (0), |
6979 | 204 previous_event_hook (0), completion_function (0), |
205 quoting_function (0), dequoting_function (0), | |
206 char_is_quoted_function (0), user_accept_line_function (0) | |
2926 | 207 { |
5775 | 208 // FIXME -- need interface to rl_add_defun, rl_initialize, and |
3519 | 209 // a function to set rl_terminal_name |
3225 | 210 |
3520 | 211 std::string term = octave_env::getenv ("TERM"); |
3519 | 212 |
213 octave_rl_set_terminal_name (term.c_str ()); | |
214 | |
215 octave_rl_initialize (); | |
2926 | 216 |
217 do_blink_matching_paren (true); | |
218 | |
5452 | 219 // Bind operate-and-get-next. |
2926 | 220 |
3519 | 221 octave_rl_add_defun ("operate-and-get-next", |
222 gnu_readline::operate_and_get_next, | |
223 octave_rl_ctrl ('O')); | |
2926 | 224 |
5452 | 225 // And the history search functions. |
2926 | 226 |
3519 | 227 octave_rl_add_defun ("history-search-backward", |
3951 | 228 gnu_readline::history_search_backward, |
3519 | 229 octave_rl_meta ('P')); |
2926 | 230 |
3519 | 231 octave_rl_add_defun ("history-search-forward", |
3951 | 232 gnu_readline::history_search_forward, |
3519 | 233 octave_rl_meta ('N')); |
2926 | 234 } |
235 | |
236 void | |
3519 | 237 gnu_readline::do_set_name (const std::string& nm) |
2926 | 238 { |
3519 | 239 ::octave_rl_set_name (nm.c_str ()); |
2926 | 240 } |
241 | |
3504 | 242 std::string |
243 gnu_readline::do_readline (const std::string& prompt, bool& eof) | |
2926 | 244 { |
3504 | 245 std::string retval; |
2926 | 246 |
3219 | 247 eof = false; |
248 | |
5247 | 249 char *line = 0; |
250 | |
5336 | 251 const char *p = prompt.c_str (); |
252 | |
5452 | 253 BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; |
5247 | 254 |
5336 | 255 line = ::octave_rl_readline (p); |
5247 | 256 |
5452 | 257 END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; |
2926 | 258 |
259 if (line) | |
260 { | |
261 retval = line; | |
262 | |
263 free (line); | |
264 } | |
3219 | 265 else |
266 eof = true; | |
2926 | 267 |
268 return retval; | |
269 } | |
270 | |
271 void | |
272 gnu_readline::do_set_input_stream (FILE *f) | |
273 { | |
3519 | 274 ::octave_rl_set_input_stream (f); |
2926 | 275 } |
276 | |
277 FILE * | |
278 gnu_readline::do_get_input_stream (void) | |
279 { | |
3519 | 280 return ::octave_rl_get_input_stream (); |
2926 | 281 } |
282 | |
283 void | |
284 gnu_readline::do_set_output_stream (FILE *f) | |
285 { | |
3519 | 286 ::octave_rl_set_output_stream (f); |
2926 | 287 } |
288 | |
289 FILE * | |
290 gnu_readline::do_get_output_stream (void) | |
291 { | |
3519 | 292 return ::octave_rl_get_output_stream (); |
2926 | 293 } |
294 | |
295 // GNU readline handles SIGWINCH, so these values have a good chance | |
296 // of being correct even if the window changes size (they may be | |
297 // wrong if, for example, the luser changes the window size while the | |
298 // pager is running, and the signal is handled by the pager instead of | |
299 // us. | |
300 | |
301 int | |
302 gnu_readline::do_terminal_rows (void) | |
303 { | |
3519 | 304 int sh = ::octave_rl_screen_height (); |
305 | |
306 return sh > 0 ? sh : 24; | |
2926 | 307 } |
308 | |
309 int | |
310 gnu_readline::do_terminal_cols (void) | |
311 { | |
3519 | 312 int sw = ::octave_rl_screen_width (); |
313 | |
314 return sw > 0 ? sw : 80; | |
2926 | 315 } |
316 | |
317 void | |
318 gnu_readline::do_clear_screen (void) | |
319 { | |
3519 | 320 ::octave_rl_clear_screen (); |
2926 | 321 } |
322 | |
3281 | 323 void |
324 gnu_readline::do_resize_terminal (void) | |
325 { | |
3519 | 326 ::octave_rl_resize_terminal (); |
3281 | 327 } |
328 | |
3504 | 329 std::string |
2926 | 330 gnu_readline::newline_chars (void) |
331 { | |
332 return "\r\n"; | |
333 } | |
334 | |
335 void | |
336 gnu_readline::do_restore_terminal_state (void) | |
337 { | |
3519 | 338 ::octave_rl_restore_terminal_state (); |
2926 | 339 } |
340 | |
341 void | |
342 gnu_readline::do_blink_matching_paren (bool flag) | |
343 { | |
3779 | 344 ::octave_rl_enable_paren_matching (flag ? 1 : 0); |
2926 | 345 } |
346 | |
347 void | |
3933 | 348 gnu_readline::do_set_basic_word_break_characters (const std::string& s) |
349 { | |
350 ::octave_rl_set_basic_word_break_characters (s.c_str ()); | |
351 } | |
352 | |
353 void | |
354 gnu_readline::do_set_completer_word_break_characters (const std::string& s) | |
355 { | |
356 ::octave_rl_set_completer_word_break_characters (s.c_str ()); | |
357 } | |
358 | |
359 void | |
3504 | 360 gnu_readline::do_set_basic_quote_characters (const std::string& s) |
2926 | 361 { |
3519 | 362 ::octave_rl_set_basic_quote_characters (s.c_str ()); |
2926 | 363 } |
364 | |
365 void | |
6979 | 366 gnu_readline::do_set_filename_quote_characters (const std::string& s) |
367 { | |
368 ::octave_rl_set_filename_quote_characters (s.c_str ()); | |
369 } | |
370 | |
371 void | |
372 gnu_readline::do_set_completer_quote_characters (const std::string& s) | |
373 { | |
374 ::octave_rl_set_completer_quote_characters (s.c_str ()); | |
375 } | |
376 | |
377 void | |
2926 | 378 gnu_readline::do_set_completion_append_character (char c) |
379 { | |
3519 | 380 ::octave_rl_set_completion_append_character (c); |
2926 | 381 } |
382 | |
383 void | |
2941 | 384 gnu_readline::do_set_completion_function (completion_fcn f) |
2926 | 385 { |
2941 | 386 completion_function = f; |
387 | |
3519 | 388 rl_attempted_completion_fcn_ptr fp |
389 = f ? gnu_readline::command_completer : 0; | |
2941 | 390 |
3519 | 391 ::octave_rl_set_completion_function (fp); |
2941 | 392 } |
393 | |
6979 | 394 void |
395 gnu_readline::do_set_quoting_function (quoting_fcn f) | |
396 { | |
397 quoting_function = f; | |
398 | |
399 rl_quoting_fcn_ptr fp | |
400 = f ? gnu_readline::command_quoter : 0; | |
401 | |
402 ::octave_rl_set_quoting_function (fp); | |
403 } | |
404 | |
405 void | |
406 gnu_readline::do_set_dequoting_function (dequoting_fcn f) | |
407 { | |
408 dequoting_function = f; | |
409 | |
410 rl_dequoting_fcn_ptr fp | |
411 = f ? gnu_readline::command_dequoter : 0; | |
412 | |
413 ::octave_rl_set_dequoting_function (fp); | |
414 } | |
415 | |
416 void | |
417 gnu_readline::do_set_char_is_quoted_function (char_is_quoted_fcn f) | |
418 { | |
419 char_is_quoted_function = f; | |
420 | |
421 rl_char_is_quoted_fcn_ptr fp | |
422 = f ? gnu_readline::command_char_is_quoted : 0; | |
423 | |
424 ::octave_rl_set_char_is_quoted_function (fp); | |
425 } | |
426 | |
427 void | |
428 gnu_readline::do_set_user_accept_line_function (user_accept_line_fcn f) | |
429 { | |
430 user_accept_line_function = f; | |
431 | |
432 if (f) | |
433 octave_rl_add_defun ("accept-line", gnu_readline::command_accept_line, | |
434 ::octave_rl_ctrl ('M')); | |
435 else | |
436 octave_rl_add_defun ("accept-line", ::octave_rl_newline, | |
437 ::octave_rl_ctrl ('M')); | |
438 } | |
439 | |
2941 | 440 gnu_readline::completion_fcn |
441 gnu_readline::do_get_completion_function (void) const | |
442 { | |
443 return completion_function; | |
2926 | 444 } |
445 | |
6979 | 446 gnu_readline::quoting_fcn |
447 gnu_readline::do_get_quoting_function (void) const | |
448 { | |
449 return quoting_function; | |
450 } | |
451 | |
452 gnu_readline::dequoting_fcn | |
453 gnu_readline::do_get_dequoting_function (void) const | |
454 { | |
455 return dequoting_function; | |
456 } | |
457 | |
458 gnu_readline::char_is_quoted_fcn | |
459 gnu_readline::do_get_char_is_quoted_function (void) const | |
460 { | |
461 return char_is_quoted_function; | |
462 } | |
463 | |
464 gnu_readline::user_accept_line_fcn | |
465 gnu_readline::do_get_user_accept_line_function (void) const | |
466 { | |
467 return user_accept_line_function; | |
468 } | |
469 | |
4604 | 470 string_vector |
471 gnu_readline::do_generate_filename_completions (const std::string& text) | |
472 { | |
473 string_vector retval; | |
474 | |
475 int n = 0; | |
476 int count = 0; | |
477 | |
478 char *fn = 0; | |
479 | |
480 while (1) | |
481 { | |
482 fn = ::octave_rl_filename_completion_function (text.c_str (), count); | |
483 | |
484 if (fn) | |
485 { | |
486 if (count == n) | |
487 { | |
488 // Famous last words: Most large directories will not | |
489 // have more than a few hundred files, so we should not | |
490 // resize too many times even if the growth is linear... | |
491 | |
492 n += 100; | |
493 retval.resize (n); | |
494 } | |
495 | |
496 retval[count++] = fn; | |
497 | |
498 free (fn); | |
499 } | |
500 else | |
501 break; | |
502 } | |
503 | |
504 retval.resize (count); | |
505 | |
506 return retval; | |
507 } | |
508 | |
2926 | 509 void |
3504 | 510 gnu_readline::do_insert_text (const std::string& text) |
2926 | 511 { |
3519 | 512 ::octave_rl_insert_text (text.c_str ()); |
2926 | 513 } |
514 | |
515 void | |
516 gnu_readline::do_newline (void) | |
517 { | |
6979 | 518 ::octave_rl_newline (1, '\n'); |
519 } | |
520 | |
521 void | |
522 gnu_readline::do_accept_line (void) | |
523 { | |
524 command_accept_line (1, '\n'); | |
2926 | 525 } |
526 | |
527 void | |
528 gnu_readline::do_clear_undo_list () | |
529 { | |
3519 | 530 ::octave_rl_clear_undo_list (); |
2926 | 531 } |
532 | |
533 void | |
6913 | 534 gnu_readline::set_startup_hook (startup_hook_fcn f) |
2926 | 535 { |
3519 | 536 previous_startup_hook = ::octave_rl_get_startup_hook (); |
2926 | 537 |
6917 | 538 if (f != previous_startup_hook) |
539 ::octave_rl_set_startup_hook (f); | |
2926 | 540 } |
541 | |
542 void | |
6913 | 543 gnu_readline::restore_startup_hook (void) |
2926 | 544 { |
3519 | 545 ::octave_rl_set_startup_hook (previous_startup_hook); |
2926 | 546 } |
547 | |
548 void | |
6913 | 549 gnu_readline::set_event_hook (event_hook_fcn f) |
3215 | 550 { |
3519 | 551 previous_event_hook = octave_rl_get_event_hook (); |
3215 | 552 |
3519 | 553 ::octave_rl_set_event_hook (f); |
3215 | 554 } |
555 | |
556 void | |
6913 | 557 gnu_readline::restore_event_hook (void) |
3215 | 558 { |
3519 | 559 ::octave_rl_set_event_hook (previous_event_hook); |
3215 | 560 } |
561 | |
562 void | |
3504 | 563 gnu_readline::do_read_init_file (const std::string& file) |
3189 | 564 { |
3519 | 565 ::octave_rl_read_init_file (file.c_str ()); |
3189 | 566 } |
567 | |
7758
8e14a01ffe9f
input.cc (Fre_read_readline_init_file): new function
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
568 void |
8e14a01ffe9f
input.cc (Fre_read_readline_init_file): new function
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
569 gnu_readline::do_re_read_init_file (void) |
8e14a01ffe9f
input.cc (Fre_read_readline_init_file): new function
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
570 { |
8e14a01ffe9f
input.cc (Fre_read_readline_init_file): new function
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
571 ::octave_rl_re_read_init_file (); |
8e14a01ffe9f
input.cc (Fre_read_readline_init_file): new function
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
572 } |
8e14a01ffe9f
input.cc (Fre_read_readline_init_file): new function
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
573 |
4143 | 574 bool |
575 gnu_readline::do_filename_completion_desired (bool arg) | |
576 { | |
577 return ::octave_rl_filename_completion_desired (arg); | |
578 } | |
579 | |
6979 | 580 bool |
581 gnu_readline::do_filename_quoting_desired (bool arg) | |
582 { | |
583 return ::octave_rl_filename_quoting_desired (arg); | |
584 } | |
585 | |
3519 | 586 int |
2926 | 587 gnu_readline::operate_and_get_next (int /* count */, int /* c */) |
588 { | |
589 // Accept the current line. | |
590 | |
6979 | 591 command_editor::accept_line (); |
2926 | 592 |
593 // Find the current line, and find the next line to use. | |
594 | |
595 int x_where = command_history::where (); | |
596 | |
597 int x_length = command_history::length (); | |
598 | |
599 if ((command_history::is_stifled () | |
600 && (x_length >= command_history::max_input_history ())) | |
601 || (x_where >= x_length - 1)) | |
602 command_history::set_mark (x_where); | |
603 else | |
604 command_history::set_mark (x_where + 1); | |
605 | |
6913 | 606 command_editor::add_startup_hook (command_history::goto_mark); |
3519 | 607 |
608 return 0; | |
2926 | 609 } |
610 | |
3951 | 611 int |
612 gnu_readline::history_search_backward (int count, int c) | |
613 { | |
614 return octave_rl_history_search_backward (count, c); | |
615 } | |
616 | |
617 int | |
618 gnu_readline::history_search_forward (int count, int c) | |
619 { | |
620 return octave_rl_history_search_forward (count, c); | |
621 } | |
622 | |
2941 | 623 char * |
624 gnu_readline::command_generator (const char *text, int state) | |
625 { | |
626 char *retval = 0; | |
627 | |
628 completion_fcn f = command_editor::get_completion_function (); | |
629 | |
3504 | 630 std::string tmp = f (text, state); |
2941 | 631 |
632 size_t len = tmp.length (); | |
633 | |
634 if (len > 0) | |
635 { | |
636 retval = static_cast<char *> (malloc (len+1)); | |
637 | |
638 strcpy (retval, tmp.c_str ()); | |
639 } | |
640 | |
641 return retval; | |
642 } | |
643 | |
6979 | 644 char * |
645 gnu_readline::command_quoter (char *text, int matches, char *qcp) | |
646 { | |
647 char *retval = 0; | |
648 | |
649 quoting_fcn f = command_editor::get_quoting_function (); | |
650 | |
651 std::string tmp = f (text, matches, *qcp); | |
652 | |
653 size_t len = tmp.length (); | |
654 | |
655 if (len > 0) | |
656 { | |
657 retval = static_cast<char *> (malloc (len+1)); | |
658 | |
659 strcpy (retval, tmp.c_str ()); | |
660 } | |
661 | |
662 return retval; | |
663 } | |
664 | |
665 char * | |
666 gnu_readline::command_dequoter (char *text, int quote) | |
667 { | |
668 char *retval = 0; | |
669 | |
670 dequoting_fcn f = command_editor::get_dequoting_function (); | |
671 | |
672 std::string tmp = f (text, quote); | |
673 | |
674 size_t len = tmp.length (); | |
675 | |
676 if (len > 0) | |
677 { | |
678 retval = static_cast<char *> (malloc (len+1)); | |
679 | |
680 strcpy (retval, tmp.c_str ()); | |
681 } | |
682 | |
683 return retval; | |
684 } | |
685 | |
686 int | |
687 gnu_readline::command_char_is_quoted (char *text, int quote) | |
688 { | |
689 char_is_quoted_fcn f = command_editor::get_char_is_quoted_function (); | |
690 | |
691 return f (text, quote); | |
692 } | |
693 | |
694 int | |
695 gnu_readline::command_accept_line (int count, int key) | |
696 { | |
697 user_accept_line_fcn f = command_editor::get_user_accept_line_function (); | |
698 | |
699 if (f) | |
700 f (::octave_rl_line_buffer ()); | |
701 | |
702 ::octave_rl_redisplay (); | |
703 | |
704 return ::octave_rl_newline (count, key); | |
705 } | |
706 | |
2941 | 707 char ** |
3519 | 708 gnu_readline::command_completer (const char *text, int, int) |
2941 | 709 { |
710 char **matches = 0; | |
3519 | 711 matches |
712 = ::octave_rl_completion_matches (text, gnu_readline::command_generator); | |
2941 | 713 return matches; |
714 } | |
715 | |
2926 | 716 #endif |
717 | |
718 class | |
719 default_command_editor : public command_editor | |
720 { | |
721 public: | |
722 | |
723 default_command_editor (void) | |
724 : command_editor (), input_stream (stdin), output_stream (stdout) { } | |
725 | |
726 ~default_command_editor (void) { } | |
727 | |
3504 | 728 std::string do_readline (const std::string& prompt, bool& eof); |
2926 | 729 |
730 void do_set_input_stream (FILE *f); | |
731 | |
732 FILE *do_get_input_stream (void); | |
733 | |
734 void do_set_output_stream (FILE *f); | |
735 | |
736 FILE *do_get_output_stream (void); | |
737 | |
4604 | 738 string_vector do_generate_filename_completions (const std::string& text); |
739 | |
3504 | 740 void do_insert_text (const std::string&); |
2926 | 741 |
742 void do_newline (void); | |
743 | |
6979 | 744 void do_accept_line (void); |
745 | |
2926 | 746 private: |
747 | |
748 FILE *input_stream; | |
749 | |
750 FILE *output_stream; | |
751 }; | |
752 | |
3504 | 753 std::string |
754 default_command_editor::do_readline (const std::string& prompt, bool& eof) | |
2926 | 755 { |
8749
5a7494ee68a3
liboctave/cmd-edit.cc, src/input.cc: use fputs instead of fprintf
John W. Eaton <jwe@octave.org>
parents:
8021
diff
changeset
|
756 fputs (prompt.c_str (), output_stream); |
2926 | 757 fflush (output_stream); |
758 | |
4527 | 759 return octave_fgetl (input_stream, eof); |
2926 | 760 } |
761 | |
762 void | |
763 default_command_editor::do_set_input_stream (FILE *f) | |
764 { | |
765 input_stream = f; | |
766 } | |
767 | |
768 FILE * | |
769 default_command_editor::do_get_input_stream (void) | |
770 { | |
771 return input_stream; | |
772 } | |
773 | |
774 void | |
775 default_command_editor::do_set_output_stream (FILE *f) | |
776 { | |
777 output_stream = f; | |
778 } | |
779 | |
780 FILE * | |
781 default_command_editor::do_get_output_stream (void) | |
782 { | |
783 return output_stream; | |
784 } | |
785 | |
4604 | 786 string_vector |
4663 | 787 default_command_editor::do_generate_filename_completions (const std::string&) |
4604 | 788 { |
5775 | 789 // FIXME |
4604 | 790 return string_vector (); |
791 } | |
792 | |
2926 | 793 void |
3504 | 794 default_command_editor::do_insert_text (const std::string&) |
2926 | 795 { |
5775 | 796 // FIXME |
2926 | 797 } |
798 | |
799 void | |
800 default_command_editor::do_newline (void) | |
801 { | |
5775 | 802 // FIXME |
2926 | 803 } |
804 | |
6979 | 805 void |
806 default_command_editor::do_accept_line (void) | |
807 { | |
808 // FIXME | |
809 } | |
810 | |
2926 | 811 bool |
812 command_editor::instance_ok (void) | |
813 { | |
814 bool retval = true; | |
815 | |
816 if (! instance) | |
817 make_command_editor (); | |
818 | |
819 if (! instance) | |
820 { | |
2941 | 821 current_liboctave_error_handler |
2926 | 822 ("unable to create command history object!"); |
823 | |
824 retval = false; | |
825 } | |
826 | |
827 return retval; | |
828 } | |
829 | |
830 void | |
831 command_editor::make_command_editor (void) | |
832 { | |
833 #if defined (USE_READLINE) | |
834 instance = new gnu_readline (); | |
835 #else | |
836 instance = new default_command_editor (); | |
837 #endif | |
838 } | |
839 | |
11980
bfa0fc8559b5
avoid using readline at all when line editing suppressed or interpreter embedded
Jaroslav Hajek <highegg@gmail.com>
parents:
8920
diff
changeset
|
840 void |
bfa0fc8559b5
avoid using readline at all when line editing suppressed or interpreter embedded
Jaroslav Hajek <highegg@gmail.com>
parents:
8920
diff
changeset
|
841 command_editor::force_default_editor (void) |
bfa0fc8559b5
avoid using readline at all when line editing suppressed or interpreter embedded
Jaroslav Hajek <highegg@gmail.com>
parents:
8920
diff
changeset
|
842 { |
bfa0fc8559b5
avoid using readline at all when line editing suppressed or interpreter embedded
Jaroslav Hajek <highegg@gmail.com>
parents:
8920
diff
changeset
|
843 delete instance; |
bfa0fc8559b5
avoid using readline at all when line editing suppressed or interpreter embedded
Jaroslav Hajek <highegg@gmail.com>
parents:
8920
diff
changeset
|
844 instance = new default_command_editor (); |
bfa0fc8559b5
avoid using readline at all when line editing suppressed or interpreter embedded
Jaroslav Hajek <highegg@gmail.com>
parents:
8920
diff
changeset
|
845 } |
bfa0fc8559b5
avoid using readline at all when line editing suppressed or interpreter embedded
Jaroslav Hajek <highegg@gmail.com>
parents:
8920
diff
changeset
|
846 |
6913 | 847 int |
848 command_editor::startup_handler (void) | |
849 { | |
850 for (startup_hook_set_iterator p = startup_hook_set.begin (); | |
851 p != startup_hook_set.end (); p++) | |
852 { | |
853 startup_hook_fcn f = *p; | |
854 | |
855 if (f) | |
856 f (); | |
857 } | |
858 | |
859 return 0; | |
860 } | |
861 | |
862 int | |
863 command_editor::event_handler (void) | |
864 { | |
7936
78400fde223e
Support for backend-to-octave event management
John W. Eaton <jwe@octave.org>
parents:
7758
diff
changeset
|
865 event_hook_lock.lock (); |
78400fde223e
Support for backend-to-octave event management
John W. Eaton <jwe@octave.org>
parents:
7758
diff
changeset
|
866 |
78400fde223e
Support for backend-to-octave event management
John W. Eaton <jwe@octave.org>
parents:
7758
diff
changeset
|
867 std::set<event_hook_fcn> hook_set (event_hook_set); |
78400fde223e
Support for backend-to-octave event management
John W. Eaton <jwe@octave.org>
parents:
7758
diff
changeset
|
868 |
78400fde223e
Support for backend-to-octave event management
John W. Eaton <jwe@octave.org>
parents:
7758
diff
changeset
|
869 event_hook_lock.unlock (); |
78400fde223e
Support for backend-to-octave event management
John W. Eaton <jwe@octave.org>
parents:
7758
diff
changeset
|
870 |
78400fde223e
Support for backend-to-octave event management
John W. Eaton <jwe@octave.org>
parents:
7758
diff
changeset
|
871 for (event_hook_set_iterator p = hook_set.begin (); |
78400fde223e
Support for backend-to-octave event management
John W. Eaton <jwe@octave.org>
parents:
7758
diff
changeset
|
872 p != hook_set.end (); p++) |
6913 | 873 { |
874 event_hook_fcn f = *p; | |
875 | |
876 if (f) | |
877 f (); | |
878 } | |
879 | |
880 return 0; | |
881 } | |
882 | |
2926 | 883 void |
3504 | 884 command_editor::set_name (const std::string& n) |
2926 | 885 { |
886 if (instance_ok ()) | |
887 instance->do_set_name (n); | |
888 } | |
889 | |
3504 | 890 std::string |
891 command_editor::readline (const std::string& prompt) | |
2926 | 892 { |
3219 | 893 bool eof; |
894 | |
895 return readline (prompt, eof); | |
896 } | |
897 | |
3504 | 898 std::string |
899 command_editor::readline (const std::string& prompt, bool& eof) | |
3219 | 900 { |
2926 | 901 return (instance_ok ()) |
3504 | 902 ? instance->do_readline (prompt, eof) : std::string (); |
2926 | 903 } |
904 | |
905 void | |
906 command_editor::set_input_stream (FILE *f) | |
907 { | |
908 if (instance_ok ()) | |
909 instance->do_set_input_stream (f); | |
910 } | |
911 | |
912 FILE * | |
913 command_editor::get_input_stream (void) | |
914 { | |
915 return (instance_ok ()) | |
916 ? instance->do_get_input_stream () : 0; | |
917 } | |
918 | |
919 void | |
920 command_editor::set_output_stream (FILE *f) | |
921 { | |
922 if (instance_ok ()) | |
923 instance->do_set_output_stream (f); | |
924 } | |
925 | |
926 FILE * | |
927 command_editor::get_output_stream (void) | |
928 { | |
929 return (instance_ok ()) | |
930 ? instance->do_get_output_stream () : 0; | |
931 } | |
932 | |
933 int | |
934 command_editor::terminal_rows (void) | |
935 { | |
936 return (instance_ok ()) | |
937 ? instance->do_terminal_rows () : -1; | |
938 } | |
939 | |
940 int | |
941 command_editor::terminal_cols (void) | |
942 { | |
943 return (instance_ok ()) | |
944 ? instance->do_terminal_cols () : -1; | |
945 } | |
946 | |
947 void | |
948 command_editor::clear_screen (void) | |
949 { | |
950 if (instance_ok ()) | |
951 instance->do_clear_screen (); | |
952 } | |
953 | |
3281 | 954 void |
955 command_editor::resize_terminal (void) | |
956 { | |
957 if (instance_ok ()) | |
958 instance->do_resize_terminal (); | |
959 } | |
960 | |
3504 | 961 std::string |
962 command_editor::decode_prompt_string (const std::string& s) | |
2926 | 963 { |
964 return (instance_ok ()) | |
3504 | 965 ? instance->do_decode_prompt_string (s) : std::string (); |
2926 | 966 } |
967 | |
968 int | |
969 command_editor::current_command_number (void) | |
970 { | |
971 return (instance_ok ()) | |
972 ? instance->command_number : 0; | |
973 } | |
974 | |
975 void | |
976 command_editor::reset_current_command_number (int n) | |
977 { | |
978 if (instance_ok ()) | |
979 instance->command_number = n; | |
980 } | |
981 | |
982 void | |
2967 | 983 command_editor::increment_current_command_number (void) |
984 { | |
985 if (instance_ok ()) | |
986 instance->command_number++; | |
987 } | |
988 | |
989 void | |
2926 | 990 command_editor::restore_terminal_state (void) |
991 { | |
992 if (instance_ok ()) | |
993 instance->do_restore_terminal_state (); | |
994 } | |
995 | |
996 void | |
997 command_editor::blink_matching_paren (bool flag) | |
998 { | |
999 if (instance_ok ()) | |
1000 instance->do_blink_matching_paren (flag); | |
1001 } | |
1002 | |
1003 void | |
3933 | 1004 command_editor::set_basic_word_break_characters (const std::string& s) |
1005 { | |
1006 if (instance_ok ()) | |
1007 instance->do_set_basic_word_break_characters (s); | |
1008 } | |
1009 | |
1010 void | |
1011 command_editor::set_completer_word_break_characters (const std::string& s) | |
1012 { | |
1013 if (instance_ok ()) | |
1014 instance->do_set_completer_word_break_characters (s); | |
1015 } | |
1016 | |
1017 void | |
3504 | 1018 command_editor::set_basic_quote_characters (const std::string& s) |
2926 | 1019 { |
1020 if (instance_ok ()) | |
3004 | 1021 instance->do_set_basic_quote_characters (s); |
2926 | 1022 } |
1023 | |
1024 void | |
6979 | 1025 command_editor::set_filename_quote_characters (const std::string& s) |
1026 { | |
1027 if (instance_ok ()) | |
1028 instance->do_set_filename_quote_characters (s); | |
1029 } | |
1030 | |
1031 void | |
1032 command_editor::set_completer_quote_characters (const std::string& s) | |
1033 { | |
1034 if (instance_ok ()) | |
1035 instance->do_set_completer_quote_characters (s); | |
1036 } | |
1037 | |
1038 void | |
2926 | 1039 command_editor::set_completion_append_character (char c) |
1040 { | |
1041 if (instance_ok ()) | |
1042 instance->do_set_completion_append_character (c); | |
1043 } | |
1044 | |
1045 void | |
2941 | 1046 command_editor::set_completion_function (completion_fcn f) |
2926 | 1047 { |
1048 if (instance_ok ()) | |
2941 | 1049 instance->do_set_completion_function (f); |
1050 } | |
1051 | |
6979 | 1052 void |
1053 command_editor::set_quoting_function (quoting_fcn f) | |
1054 { | |
1055 if (instance_ok ()) | |
1056 instance->do_set_quoting_function (f); | |
1057 } | |
1058 | |
1059 void | |
1060 command_editor::set_dequoting_function (dequoting_fcn f) | |
1061 { | |
1062 if (instance_ok ()) | |
1063 instance->do_set_dequoting_function (f); | |
1064 } | |
1065 | |
1066 void | |
1067 command_editor::set_char_is_quoted_function (char_is_quoted_fcn f) | |
1068 { | |
1069 if (instance_ok ()) | |
1070 instance->do_set_char_is_quoted_function (f); | |
1071 } | |
1072 | |
1073 void | |
1074 command_editor::set_user_accept_line_function (user_accept_line_fcn f) | |
1075 { | |
1076 if (instance_ok ()) | |
1077 instance->do_set_user_accept_line_function (f); | |
1078 } | |
1079 | |
2941 | 1080 command_editor::completion_fcn |
1081 command_editor::get_completion_function (void) | |
1082 { | |
1083 return (instance_ok ()) | |
1084 ? instance->do_get_completion_function () : 0; | |
2926 | 1085 } |
1086 | |
6979 | 1087 command_editor::quoting_fcn |
1088 command_editor::get_quoting_function (void) | |
1089 { | |
1090 return (instance_ok ()) | |
1091 ? instance->do_get_quoting_function () : 0; | |
1092 } | |
1093 | |
1094 command_editor::dequoting_fcn | |
1095 command_editor::get_dequoting_function (void) | |
1096 { | |
1097 return (instance_ok ()) | |
1098 ? instance->do_get_dequoting_function () : 0; | |
1099 } | |
1100 | |
1101 command_editor::char_is_quoted_fcn | |
1102 command_editor::get_char_is_quoted_function (void) | |
1103 { | |
1104 return (instance_ok ()) | |
1105 ? instance->do_get_char_is_quoted_function () : 0; | |
1106 } | |
1107 | |
1108 command_editor::user_accept_line_fcn | |
1109 command_editor::get_user_accept_line_function (void) | |
1110 { | |
1111 return (instance_ok ()) | |
1112 ? instance->do_get_user_accept_line_function () : 0; | |
1113 } | |
1114 | |
4604 | 1115 string_vector |
1116 command_editor::generate_filename_completions (const std::string& text) | |
1117 { | |
1118 return (instance_ok ()) | |
1119 ? instance->do_generate_filename_completions (text) : string_vector (); | |
1120 } | |
1121 | |
2926 | 1122 void |
3504 | 1123 command_editor::insert_text (const std::string& text) |
2926 | 1124 { |
1125 if (instance_ok ()) | |
1126 instance->do_insert_text (text); | |
1127 } | |
1128 | |
1129 void | |
1130 command_editor::newline (void) | |
1131 { | |
1132 if (instance_ok ()) | |
1133 instance->do_newline (); | |
1134 } | |
1135 | |
1136 void | |
6979 | 1137 command_editor::accept_line (void) |
1138 { | |
1139 if (instance_ok ()) | |
1140 instance->do_accept_line (); | |
1141 } | |
1142 | |
1143 void | |
2926 | 1144 command_editor::clear_undo_list (void) |
1145 { | |
1146 if (instance_ok ()) | |
1147 instance->do_clear_undo_list (); | |
1148 } | |
1149 | |
1150 void | |
6913 | 1151 command_editor::add_startup_hook (startup_hook_fcn f) |
2926 | 1152 { |
1153 if (instance_ok ()) | |
6913 | 1154 { |
1155 startup_hook_set.insert (f); | |
1156 | |
1157 instance->set_startup_hook (startup_handler); | |
1158 } | |
2926 | 1159 } |
1160 | |
1161 void | |
6913 | 1162 command_editor::remove_startup_hook (startup_hook_fcn f) |
2926 | 1163 { |
1164 if (instance_ok ()) | |
6913 | 1165 { |
1166 startup_hook_set_iterator p = startup_hook_set.find (f); | |
1167 | |
1168 if (p != startup_hook_set.end ()) | |
6916 | 1169 startup_hook_set.erase (p); |
6913 | 1170 |
1171 if (startup_hook_set.empty ()) | |
1172 instance->restore_startup_hook (); | |
1173 } | |
2926 | 1174 } |
1175 | |
3189 | 1176 void |
6913 | 1177 command_editor::add_event_hook (event_hook_fcn f) |
3215 | 1178 { |
7936
78400fde223e
Support for backend-to-octave event management
John W. Eaton <jwe@octave.org>
parents:
7758
diff
changeset
|
1179 octave_autolock guard (event_hook_lock); |
78400fde223e
Support for backend-to-octave event management
John W. Eaton <jwe@octave.org>
parents:
7758
diff
changeset
|
1180 |
3215 | 1181 if (instance_ok ()) |
6913 | 1182 { |
1183 event_hook_set.insert (f); | |
1184 | |
1185 instance->set_event_hook (event_handler); | |
1186 } | |
3215 | 1187 } |
1188 | |
1189 void | |
6913 | 1190 command_editor::remove_event_hook (event_hook_fcn f) |
3215 | 1191 { |
7936
78400fde223e
Support for backend-to-octave event management
John W. Eaton <jwe@octave.org>
parents:
7758
diff
changeset
|
1192 octave_autolock guard (event_hook_lock); |
78400fde223e
Support for backend-to-octave event management
John W. Eaton <jwe@octave.org>
parents:
7758
diff
changeset
|
1193 |
3215 | 1194 if (instance_ok ()) |
6913 | 1195 { |
1196 event_hook_set_iterator p = event_hook_set.find (f); | |
1197 | |
1198 if (p != event_hook_set.end ()) | |
1199 event_hook_set.erase (p); | |
1200 | |
1201 if (event_hook_set.empty ()) | |
1202 instance->restore_event_hook (); | |
1203 } | |
3215 | 1204 } |
1205 | |
1206 void | |
5872 | 1207 command_editor::read_init_file (const std::string& file_arg) |
3189 | 1208 { |
1209 if (instance_ok ()) | |
5872 | 1210 { |
1211 std::string file = file_ops::tilde_expand (file_arg); | |
1212 | |
1213 instance->do_read_init_file (file); | |
1214 } | |
3189 | 1215 } |
1216 | |
7758
8e14a01ffe9f
input.cc (Fre_read_readline_init_file): new function
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
1217 void |
8e14a01ffe9f
input.cc (Fre_read_readline_init_file): new function
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
1218 command_editor::re_read_init_file (void) |
8e14a01ffe9f
input.cc (Fre_read_readline_init_file): new function
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
1219 { |
8e14a01ffe9f
input.cc (Fre_read_readline_init_file): new function
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
1220 if (instance_ok ()) |
8e14a01ffe9f
input.cc (Fre_read_readline_init_file): new function
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
1221 instance->do_re_read_init_file (); |
8e14a01ffe9f
input.cc (Fre_read_readline_init_file): new function
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
1222 } |
8e14a01ffe9f
input.cc (Fre_read_readline_init_file): new function
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
1223 |
4143 | 1224 bool |
1225 command_editor::filename_completion_desired (bool arg) | |
1226 { | |
1227 return (instance_ok ()) | |
1228 ? instance->do_filename_completion_desired (arg) : false; | |
1229 } | |
1230 | |
6979 | 1231 bool |
1232 command_editor::filename_quoting_desired (bool arg) | |
1233 { | |
1234 return (instance_ok ()) | |
1235 ? instance->do_filename_quoting_desired (arg) : false; | |
1236 } | |
1237 | |
2926 | 1238 // Return a string which will be printed as a prompt. The string may |
1239 // contain special characters which are decoded as follows: | |
1240 // | |
5442 | 1241 // \a bell (ascii 07) |
2926 | 1242 // \d the date |
5442 | 1243 // \e escape (ascii 033) |
1244 // \h the hostname up to the first `.' | |
1245 // \H the hostname | |
2926 | 1246 // \n CRLF |
5442 | 1247 // \r CR |
2926 | 1248 // \s the name of the shell (program) |
5442 | 1249 // \t the time |
1250 // \T the time in 12-hour hh:mm:ss format | |
1251 // \@ the time in 12-hour hh:mm am/pm format | |
1252 // \A the time in 24-hour hh:mm format | |
1253 // \u your username | |
2926 | 1254 // \w the current working directory |
1255 // \W the last element of PWD | |
5442 | 1256 // \! the history number of this command |
2926 | 1257 // \# the command number of this command |
1258 // \$ a $ or a # if you are root | |
5442 | 1259 // \nnn character code nnn in octal |
2926 | 1260 // \\ a backslash |
5442 | 1261 // \[ begin a sequence of non-printing chars |
1262 // \] end a sequence of non-printing chars | |
2926 | 1263 |
3504 | 1264 std::string |
1265 command_editor::do_decode_prompt_string (const std::string& s) | |
2926 | 1266 { |
3504 | 1267 std::string result; |
1268 std::string temp; | |
2926 | 1269 size_t i = 0; |
1270 size_t slen = s.length (); | |
1271 int c; | |
1272 | |
1273 while (i < slen) | |
1274 { | |
1275 c = s[i]; | |
1276 | |
1277 i++; | |
1278 | |
1279 if (c == '\\') | |
1280 { | |
1281 c = s[i]; | |
1282 | |
1283 switch (c) | |
1284 { | |
1285 case '0': | |
1286 case '1': | |
1287 case '2': | |
1288 case '3': | |
1289 case '4': | |
1290 case '5': | |
1291 case '6': | |
1292 case '7': | |
1293 // Maybe convert an octal number. | |
1294 { | |
1295 int n = read_octal (s.substr (i, 3)); | |
1296 | |
1297 temp = "\\"; | |
1298 | |
1299 if (n != -1) | |
1300 { | |
1301 i += 3; | |
1302 temp[0] = n; | |
1303 } | |
1304 | |
1305 c = 0; | |
1306 goto add_string; | |
1307 } | |
5442 | 1308 |
1309 case 'a': | |
1310 { | |
1311 temp = '\a'; | |
1312 | |
1313 goto add_string; | |
1314 } | |
1315 | |
1316 case 'e': | |
1317 { | |
1318 temp = '\033'; | |
1319 | |
1320 goto add_string; | |
1321 } | |
1322 | |
1323 case 'r': | |
1324 { | |
1325 temp = '\r'; | |
1326 | |
1327 goto add_string; | |
1328 } | |
1329 | |
1330 case 'd': | |
2926 | 1331 case 't': |
5442 | 1332 case 'T': |
1333 case '@': | |
1334 case 'A': | |
2926 | 1335 // Make the current time/date into a string. |
1336 { | |
5442 | 1337 octave_localtime now; |
2926 | 1338 |
5442 | 1339 if (c == 'd') |
1340 temp = now.strftime ("%a %b %d"); | |
1341 else if (c == 't') | |
1342 temp = now.strftime ("%H:%M:%S"); | |
1343 else if (c == 'T') | |
1344 temp = now.strftime ("%I:%M:%S"); | |
1345 else if (c == '@') | |
1346 temp = now.strftime ("%I:%M %p"); | |
1347 else if (c == 'A') | |
1348 temp = now.strftime ("%H:%M"); | |
2926 | 1349 |
1350 goto add_string; | |
1351 } | |
1352 | |
1353 case 'n': | |
1354 { | |
1355 temp = newline_chars (); | |
1356 | |
1357 goto add_string; | |
1358 } | |
1359 | |
1360 case 's': | |
1361 { | |
1362 temp = octave_env::get_program_name (); | |
1363 temp = octave_env::base_pathname (temp); | |
1364 | |
1365 goto add_string; | |
1366 } | |
5442 | 1367 |
2926 | 1368 case 'w': |
1369 case 'W': | |
1370 { | |
1371 temp = octave_env::getcwd (); | |
1372 | |
5442 | 1373 std::string home_dir = octave_env::get_home_directory (); |
1374 | |
1375 if (c == 'W' && (home_dir.empty () || temp != home_dir)) | |
2926 | 1376 { |
5442 | 1377 if (temp != "/" && temp != "//") |
1378 { | |
1379 size_t pos = temp.rfind ('/'); | |
2926 | 1380 |
8021 | 1381 if (pos != std::string::npos && pos != 0) |
5442 | 1382 temp = temp.substr (pos + 1); |
1383 } | |
2926 | 1384 } |
1385 else | |
1386 temp = octave_env::polite_directory_format (temp); | |
1387 | |
1388 goto add_string; | |
1389 } | |
5442 | 1390 |
2926 | 1391 case 'u': |
1392 { | |
1393 temp = octave_env::get_user_name (); | |
1394 | |
1395 goto add_string; | |
1396 } | |
1397 | |
1398 case 'H': | |
1399 { | |
1400 temp = octave_env::get_host_name (); | |
1401 | |
1402 goto add_string; | |
1403 } | |
1404 | |
1405 case 'h': | |
1406 { | |
1407 temp = octave_env::get_host_name (); | |
1408 | |
1409 size_t pos = temp.find ('.'); | |
1410 | |
8021 | 1411 if (pos != std::string::npos) |
2926 | 1412 temp.resize (pos); |
1413 | |
1414 goto add_string; | |
1415 } | |
1416 | |
1417 case '#': | |
1418 { | |
1419 char number_buffer[128]; | |
1420 sprintf (number_buffer, "%d", command_number); | |
1421 temp = number_buffer; | |
1422 | |
1423 goto add_string; | |
1424 } | |
1425 | |
1426 case '!': | |
1427 { | |
1428 char number_buffer[128]; | |
1429 int num = command_history::current_number (); | |
1430 if (num > 0) | |
1431 sprintf (number_buffer, "%d", num); | |
1432 else | |
1433 strcpy (number_buffer, "!"); | |
1434 temp = number_buffer; | |
1435 | |
1436 goto add_string; | |
1437 } | |
1438 | |
1439 case '$': | |
1440 { | |
4062 | 1441 #if defined (HAVE_GETEUID) |
2926 | 1442 temp = (::geteuid () == 0 ? "#" : "$"); |
4062 | 1443 #else |
1444 temp = "$"; | |
1445 #endif | |
2926 | 1446 |
1447 goto add_string; | |
1448 } | |
1449 | |
1450 #if defined (USE_READLINE) | |
1451 case '[': | |
1452 case ']': | |
1453 { | |
6940 | 1454 temp.resize (1); |
2926 | 1455 |
6940 | 1456 temp[0] = ((c == '[') |
3519 | 1457 ? ::octave_rl_prompt_start_ignore () |
1458 : ::octave_rl_prompt_end_ignore ()); | |
2926 | 1459 |
1460 goto add_string; | |
1461 } | |
1462 #endif | |
1463 | |
1464 case '\\': | |
1465 { | |
1466 temp = "\\"; | |
1467 | |
1468 goto add_string; | |
1469 } | |
1470 | |
1471 default: | |
1472 { | |
1473 temp = "\\ "; | |
1474 temp[1] = c; | |
1475 | |
1476 goto add_string; | |
1477 } | |
1478 | |
1479 add_string: | |
1480 { | |
1481 if (c) | |
1482 i++; | |
1483 | |
1484 result.append (temp); | |
1485 | |
1486 break; | |
1487 } | |
1488 } | |
1489 } | |
1490 else | |
1491 result += c; | |
1492 } | |
1493 | |
1494 return result; | |
1495 } | |
1496 | |
1497 // Return the octal number parsed from STRING, or -1 to indicate that | |
1498 // the string contained a bad number. | |
1499 | |
1500 int | |
3504 | 1501 command_editor::read_octal (const std::string& s) |
2926 | 1502 { |
1503 int result = 0; | |
1504 int digits = 0; | |
1505 | |
1506 size_t i = 0; | |
1507 size_t slen = s.length (); | |
1508 | |
1509 while (i < slen && s[i] >= '0' && s[i] < '8') | |
1510 { | |
1511 digits++; | |
1512 result = (result * 8) + s[i] - '0'; | |
1513 i++; | |
1514 } | |
1515 | |
1516 if (! digits || result > 0777 || i < slen) | |
1517 result = -1; | |
1518 | |
1519 return result; | |
1520 } | |
1521 | |
1522 void | |
1523 command_editor::error (int err_num) | |
1524 { | |
2941 | 1525 current_liboctave_error_handler ("%s", strerror (err_num)); |
2926 | 1526 } |
1527 | |
1528 void | |
3504 | 1529 command_editor::error (const std::string& s) |
2926 | 1530 { |
2941 | 1531 current_liboctave_error_handler ("%s", s.c_str ()); |
2926 | 1532 } |
1533 | |
1534 /* | |
1535 ;;; Local Variables: *** | |
1536 ;;; mode: C++ *** | |
1537 ;;; End: *** | |
1538 */ |