X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=lib%2Freadline%2Freadline.c;h=3efd8102e66c0590c351b06e43cca6888f522e56;hb=f73dda092b33638d2d5e9c35375f687a607b5403;hp=622811fc11e3e8cef03de968e9978fff0e2953f0;hpb=b72432fdcc59300c6fe7c9d6c8a31ad3447933f5;p=platform%2Fupstream%2Fbash.git diff --git a/lib/readline/readline.c b/lib/readline/readline.c index 622811f..3efd810 100644 --- a/lib/readline/readline.c +++ b/lib/readline/readline.c @@ -8,7 +8,7 @@ The GNU Readline Library is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License - as published by the Free Software Foundation; either version 1, or + as published by the Free Software Foundation; either version 2, or (at your option) any later version. The GNU Readline Library is distributed in the hope that it will be @@ -19,7 +19,7 @@ The GNU General Public License is often shipped with GNU software, and is generally kept in a file called COPYING or LICENSE. If you do not have a copy of the license, write to the Free Software Foundation, - 675 Mass Ave, Cambridge, MA 02139, USA. */ + 59 Temple Place, Suite 330, Boston, MA 02111 USA. */ #define READLINE_LIBRARY #if defined (HAVE_CONFIG_H) @@ -47,7 +47,6 @@ # include #endif -#include #include #include "posixjmp.h" @@ -63,117 +62,31 @@ #include "readline.h" #include "history.h" +#include "rlprivate.h" +#include "rlshell.h" +#include "xmalloc.h" + #ifndef RL_LIBRARY_VERSION -# define RL_LIBRARY_VERSION "4.0" +# define RL_LIBRARY_VERSION "4.2a" #endif -/* Evaluates its arguments multiple times. */ -#define SWAP(s, e) do { int t; t = s; s = e; e = t; } while (0) - -/* NOTE: Functions and variables prefixed with `_rl_' are - pseudo-global: they are global so they can be shared - between files in the readline library, but are not intended - to be visible to readline callers. */ - -/* Variables and functions imported from terminal.c */ -extern int _rl_init_terminal_io (); -extern void _rl_enable_meta_key (); -#ifdef _MINIX -extern void _rl_output_character_function (); -#else -extern int _rl_output_character_function (); +#ifndef RL_READLINE_VERSION +# define RL_READLINE_VERSION 0x0402 #endif -extern int _rl_enable_meta; -extern int _rl_term_autowrap; -extern int screenwidth, screenheight, screenchars; - -/* Variables and functions imported from rltty.c. */ -extern void rl_prep_terminal (), rl_deprep_terminal (); -extern void rltty_set_default_bindings (); - -/* Functions imported from util.c. */ -extern void _rl_abort_internal (); -extern void rl_extend_line_buffer (); -extern int alphabetic (); - -/* Functions imported from bind.c. */ -extern void _rl_bind_if_unbound (); - -/* Functions imported from input.c. */ -extern int _rl_any_typein (); -extern void _rl_insert_typein (); -extern int rl_read_key (); - -/* Functions imported from nls.c */ -extern int _rl_init_eightbit (); - -/* Functions imported from shell.c */ -extern char *get_env_value (); - -/* External redisplay functions and variables from display.c */ -extern void _rl_move_vert (); -extern void _rl_update_final (); -extern void _rl_clear_to_eol (); -extern void _rl_clear_screen (); -extern void _rl_erase_entire_line (); - -extern void _rl_erase_at_end_of_line (); -extern void _rl_move_cursor_relative (); - -extern int _rl_vis_botlin; -extern int _rl_last_c_pos; -extern int _rl_horizontal_scroll_mode; -extern int rl_display_fixed; -extern int _rl_suppress_redisplay; -extern char *rl_display_prompt; - -/* Variables imported from complete.c. */ -extern char *rl_completer_word_break_characters; -extern char *rl_basic_word_break_characters; -extern int rl_completion_query_items; -extern int rl_complete_with_tilde_expansion; - -/* Variables and functions from macro.c. */ -extern void _rl_add_macro_char (); -extern void _rl_with_macro_input (); -extern int _rl_next_macro_key (); -extern int _rl_defining_kbd_macro; - -#if defined (VI_MODE) -/* Functions imported from vi_mode.c. */ -extern void _rl_vi_set_last (); -extern void _rl_vi_reset_last (); -extern void _rl_vi_done_inserting (); -extern int _rl_vi_textmod_command (); -extern void _rl_vi_initialize_line (); -#endif /* VI_MODE */ - -extern UNDO_LIST *rl_undo_list; -extern int _rl_doing_an_undo; +/* Evaluates its arguments multiple times. */ +#define SWAP(s, e) do { int t; t = s; s = e; e = t; } while (0) /* Forward declarations used in this file. */ -void _rl_free_history_entry (); - -int _rl_dispatch (); -int _rl_init_argument (); - -static char *readline_internal (); -static void readline_initialize_everything (); -static void start_using_history (); -static void bind_arrow_keys (); +void _rl_free_history_entry PARAMS((HIST_ENTRY *)); -#if !defined (__GO32__) -static void readline_default_bindings (); -#endif /* !__GO32__ */ +static char *readline_internal PARAMS((void)); +static void readline_initialize_everything PARAMS((void)); +static void start_using_history PARAMS((void)); +static void bind_arrow_keys PARAMS((void)); +static int rl_change_case PARAMS((int, int)); -#if defined (__GO32__) -# include -# include -# undef HANDLE_SIGNALS -#endif /* __GO32__ */ - -extern char *xmalloc (), *xrealloc (); +static void readline_default_bindings PARAMS((void)); /* **************************************************************** */ /* */ @@ -181,7 +94,12 @@ extern char *xmalloc (), *xrealloc (); /* */ /* **************************************************************** */ -char *rl_library_version = RL_LIBRARY_VERSION; +const char *rl_library_version = RL_LIBRARY_VERSION; + +int rl_readline_version = RL_READLINE_VERSION; + +/* True if this is `real' readline as opposed to some stub substitute. */ +int rl_gnu_readline_p = 1; /* A pointer to the keymap that is currently in use. By default, it is the standard emacs keymap. */ @@ -210,8 +128,13 @@ int rl_arg_sign = 1; /* Non-zero means we have been called at least once before. */ static int rl_initialized; +#if 0 /* If non-zero, this program is running in an EMACS buffer. */ static int running_in_emacs; +#endif + +/* Flags word encapsulating the current readline state. */ +int rl_readline_state = RL_STATE_NONE; /* The current offset in the current input line. */ int rl_point; @@ -226,7 +149,7 @@ int rl_end; int rl_done; /* The last function executed by readline. */ -Function *rl_last_func = (Function *)NULL; +rl_command_func_t *rl_last_func = (rl_command_func_t *)NULL; /* Top level environment for readline_internal (). */ procenv_t readline_top_level; @@ -238,24 +161,31 @@ FILE *_rl_in_stream, *_rl_out_stream; FILE *rl_instream = (FILE *)NULL; FILE *rl_outstream = (FILE *)NULL; -/* Non-zero means echo characters as they are read. */ -int readline_echoing_p = 1; +/* Non-zero means echo characters as they are read. Defaults to no echo; + set to 1 if there is a controlling terminal, we can get its attributes, + and the attributes include `echo'. Look at rltty.c:prepare_terminal_settings + for the code that sets it. */ +int readline_echoing_p = 0; /* Current prompt. */ -char *rl_prompt; +char *rl_prompt = (char *)NULL; int rl_visible_prompt_length = 0; +/* Set to non-zero by calling application if it has already printed rl_prompt + and does not want readline to do it the first time. */ +int rl_already_prompted = 0; + /* The number of characters read in order to type this complete command. */ int rl_key_sequence_length = 0; /* If non-zero, then this is the address of a function to call just before readline_internal_setup () prints the first prompt. */ -Function *rl_startup_hook = (Function *)NULL; +rl_hook_func_t *rl_startup_hook = (rl_hook_func_t *)NULL; /* If non-zero, this is the address of a function to call just before readline_internal_setup () returns and readline_internal starts reading input characters. */ -Function *rl_pre_input_hook = (Function *)NULL; +rl_hook_func_t *rl_pre_input_hook = (rl_hook_func_t *)NULL; /* What we use internally. You should always refer to RL_LINE_BUFFER. */ static char *the_line; @@ -268,7 +198,7 @@ int _rl_eof_char = CTRL ('D'); int rl_pending_input = 0; /* Pointer to a useful terminal name. */ -char *rl_terminal_name = (char *)NULL; +const char *rl_terminal_name = (const char *)NULL; /* Non-zero means to always use horizontal scrolling in line display. */ int _rl_horizontal_scroll_mode = 0; @@ -290,11 +220,15 @@ Keymap rl_executing_keymap; /* Non-zero means to erase entire line, including prompt, on empty input lines. */ int rl_erase_empty_line = 0; +/* Non-zero means to read only this many characters rather than up to a + character bound to accept-line. */ +int rl_num_chars_to_read; + /* Line buffer and maintenence. */ char *rl_line_buffer = (char *)NULL; int rl_line_buffer_len = 0; -/* Forward declarations used by the display and termcap code. */ +/* Forward declarations used by the display, termcap, and history code. */ /* **************************************************************** */ /* */ @@ -315,6 +249,14 @@ int _rl_convert_meta_chars_to_ascii = 1; rather than as a meta-prefixed escape sequence. */ int _rl_output_meta_chars = 0; +/* If non-zero, rl_get_previous_history and rl_get_next_history attempt + to preserve the value of rl_point from line to line. */ +int _rl_history_preserve_point = 0; + +/* Saved target point for when _rl_history_preserve_point is set. Special + value of -1 means that point is at the end of the line. */ +static int _rl_history_saved_point = -1; + /* **************************************************************** */ /* */ /* Top Level Functions */ @@ -324,24 +266,35 @@ int _rl_output_meta_chars = 0; /* Non-zero means treat 0200 bit in terminal input as Meta bit. */ int _rl_meta_flag = 0; /* Forward declaration */ +/* Set up the prompt and expand it. Called from readline() and + rl_callback_handler_install (). */ +int +rl_set_prompt (prompt) + const char *prompt; +{ + FREE (rl_prompt); + rl_prompt = prompt ? savestring (prompt) : (char *)NULL; + + rl_visible_prompt_length = rl_expand_prompt (rl_prompt); + return 0; +} + /* Read a line of input. Prompt with PROMPT. An empty PROMPT means none. A return value of NULL means that EOF was encountered. */ char * readline (prompt) - char *prompt; + const char *prompt; { char *value; - rl_prompt = prompt; - /* If we are at EOF return a NULL string. */ if (rl_pending_input == EOF) { - rl_pending_input = 0; + rl_clear_pending_input (); return ((char *)NULL); } - rl_visible_prompt_length = rl_expand_prompt (rl_prompt); + rl_set_prompt (prompt); rl_initialize (); (*rl_prep_term_function) (_rl_meta_flag); @@ -369,6 +322,8 @@ readline (prompt) STATIC_CALLBACK void readline_internal_setup () { + char *nprompt; + _rl_in_stream = rl_instream; _rl_out_stream = rl_outstream; @@ -377,15 +332,20 @@ readline_internal_setup () if (readline_echoing_p == 0) { - if (rl_prompt) + if (rl_prompt && rl_already_prompted == 0) { - fprintf (_rl_out_stream, "%s", rl_prompt); + nprompt = _rl_strip_prompt (rl_prompt); + fprintf (_rl_out_stream, "%s", nprompt); fflush (_rl_out_stream); + free (nprompt); } } else { - rl_on_new_line (); + if (rl_prompt && rl_already_prompted) + rl_on_new_line_with_prompt (); + else + rl_on_new_line (); (*rl_redisplay_function) (); #if defined (VI_MODE) if (rl_editing_mode == vi_mode) @@ -422,7 +382,7 @@ readline_internal_teardown (eof) /* At any rate, it is highly likely that this line has an undo list. Get rid of it now. */ if (rl_undo_list) - free_undo_list (); + rl_free_undo_list (); return (eof ? (char *)NULL : savestring (the_line)); } @@ -458,7 +418,9 @@ readline_internal_charloop () rl_key_sequence_length = 0; } + RL_SETSTATE(RL_STATE_READCMD); c = rl_read_key (); + RL_UNSETSTATE(RL_STATE_READCMD); /* EOF typed to a non-blank line is a . */ if (c == EOF && rl_end) @@ -469,6 +431,7 @@ readline_internal_charloop () if (((c == _rl_eof_char && lastc != c) || c == EOF) && !rl_end) { #if defined (READLINE_CALLBACKS) + RL_SETSTATE(RL_STATE_DONE); return (rl_done = 1); #else eof_found = 1; @@ -477,7 +440,7 @@ readline_internal_charloop () } lastc = c; - _rl_dispatch (c, _rl_keymap); + _rl_dispatch ((unsigned char)c, _rl_keymap); /* If there was no change in _rl_last_command_was_kill, then no kill has taken place. Note that if input is pending we are reading @@ -492,6 +455,12 @@ readline_internal_charloop () rl_vi_check (); #endif /* VI_MODE */ + if (rl_num_chars_to_read && rl_end >= rl_num_chars_to_read) + { + (*rl_redisplay_function) (); + rl_newline (1, '\n'); + } + if (rl_done == 0) (*rl_redisplay_function) (); @@ -559,7 +528,7 @@ _rl_dispatch (key, map) { int r, newkey; char *macro; - Function *func; + rl_command_func_t *func; if (META_CHAR (key) && _rl_convert_meta_chars_to_ascii) { @@ -573,7 +542,7 @@ _rl_dispatch (key, map) return (_rl_dispatch (key, map)); } else - ding (); + rl_ding (); return 0; } @@ -585,7 +554,7 @@ _rl_dispatch (key, map) { case ISFUNC: func = map[key].function; - if (func != (Function *)NULL) + if (func) { /* Special case rl_do_lowercase_version (). */ if (func == rl_do_lowercase_version) @@ -598,13 +567,15 @@ _rl_dispatch (key, map) #endif rl_dispatching = 1; + RL_SETSTATE(RL_STATE_DISPATCHING); r = (*map[key].function)(rl_numeric_arg * rl_arg_sign, key); + RL_UNSETSTATE(RL_STATE_DISPATCHING); rl_dispatching = 0; /* If we have input pending, then the last command was a prefix command. Don't change the state of rl_last_func. Otherwise, remember the last command executed in this variable. */ - if (!rl_pending_input && map[key].function != rl_digit_argument) + if (rl_pending_input == 0 && map[key].function != rl_digit_argument) rl_last_func = map[key].function; } else @@ -615,10 +586,24 @@ _rl_dispatch (key, map) break; case ISKMAP: - if (map[key].function != (Function *)NULL) + if (map[key].function != 0) { rl_key_sequence_length++; + + if (key == ESC) + RL_SETSTATE(RL_STATE_METANEXT); + RL_SETSTATE(RL_STATE_MOREINPUT); newkey = rl_read_key (); + RL_UNSETSTATE(RL_STATE_MOREINPUT); + if (key == ESC) + RL_UNSETSTATE(RL_STATE_METANEXT); + + if (newkey < 0) + { + _rl_abort_internal (); + return -1; + } + r = _rl_dispatch (newkey, FUNCTION_TO_KEYMAP (map, key)); } else @@ -629,7 +614,7 @@ _rl_dispatch (key, map) break; case ISMACR: - if (map[key].function != (Function *)NULL) + if (map[key].function != 0) { macro = savestring ((char *)map[key].function); _rl_with_macro_input (macro); @@ -659,8 +644,11 @@ rl_initialize () terminal and data structures. */ if (!rl_initialized) { + RL_SETSTATE(RL_STATE_INITIALIZING); readline_initialize_everything (); + RL_UNSETSTATE(RL_STATE_INITIALIZING); rl_initialized++; + RL_SETSTATE(RL_STATE_INITIALIZED); } /* Initalize the current line information. */ @@ -668,6 +656,7 @@ rl_initialize () /* We aren't done yet. We haven't even gotten started yet! */ rl_done = 0; + RL_UNSETSTATE(RL_STATE_DONE); /* Tell the history routines what is going on. */ start_using_history (); @@ -676,7 +665,7 @@ rl_initialize () rl_reset_line_state (); /* No such function typed yet. */ - rl_last_func = (Function *)NULL; + rl_last_func = (rl_command_func_t *)NULL; /* Parsing of key-bindings begins in an enabled state. */ _rl_parsing_conditionalized_out = 0; @@ -689,6 +678,7 @@ rl_initialize () return 0; } +#if 0 #if defined (__EMX__) static void _emx_build_environ () @@ -712,18 +702,23 @@ _emx_build_environ () *tp = 0; } #endif /* __EMX__ */ +#endif /* Initialize the entire state of the world. */ static void readline_initialize_everything () { +#if 0 #if defined (__EMX__) if (environ == 0) _emx_build_environ (); #endif +#endif - /* Find out if we are running in Emacs. */ - running_in_emacs = get_env_value ("EMACS") != (char *)0; +#if 0 + /* Find out if we are running in Emacs -- UNUSED. */ + running_in_emacs = sh_get_env_value ("EMACS") != (char *)0; +#endif /* Set up input and output if they are not already set up. */ if (!rl_instream) @@ -740,15 +735,15 @@ readline_initialize_everything () /* Allocate data structures. */ if (rl_line_buffer == 0) - rl_line_buffer = xmalloc (rl_line_buffer_len = DEFAULT_BUFFER_SIZE); + rl_line_buffer = (char *)xmalloc (rl_line_buffer_len = DEFAULT_BUFFER_SIZE); /* Initialize the terminal interface. */ - _rl_init_terminal_io ((char *)NULL); + if (rl_terminal_name == 0) + rl_terminal_name = sh_get_env_value ("TERM"); + _rl_init_terminal_io (rl_terminal_name); -#if !defined (__GO32__) /* Bind tty characters to readline functions. */ readline_default_bindings (); -#endif /* !__GO32__ */ /* Initialize the function names. */ rl_initialize_funmap (); @@ -762,8 +757,8 @@ readline_initialize_everything () /* XXX */ if (_rl_horizontal_scroll_mode && _rl_term_autowrap) { - screenwidth--; - screenchars -= screenheight; + _rl_screenwidth--; + _rl_screenchars -= _rl_screenheight; } /* Override the effect of any `set keymap' assignments in the @@ -789,14 +784,25 @@ readline_initialize_everything () static void readline_default_bindings () { - rltty_set_default_bindings (_rl_keymap); + rl_tty_set_default_bindings (_rl_keymap); } static void bind_arrow_keys_internal () { - Function *f; + rl_command_func_t *f; +#if defined (__MSDOS__) + f = rl_function_of_keyseq ("\033[0A", _rl_keymap, (int *)NULL); + if (!f || f == rl_do_lowercase_version) + { + _rl_bind_if_unbound ("\033[0A", rl_get_previous_history); + _rl_bind_if_unbound ("\033[0B", rl_backward); + _rl_bind_if_unbound ("\033[0C", rl_forward); + _rl_bind_if_unbound ("\033[0D", rl_get_next_history); + } +#endif + f = rl_function_of_keyseq ("\033[A", _rl_keymap, (int *)NULL); if (!f || f == rl_do_lowercase_version) { @@ -852,19 +858,29 @@ rl_digit_loop () rl_save_prompt (); + RL_SETSTATE(RL_STATE_NUMERICARG); sawminus = sawdigits = 0; while (1) { if (rl_numeric_arg > 1000000) { sawdigits = rl_explicit_arg = rl_numeric_arg = 0; - ding (); + rl_ding (); rl_restore_prompt (); rl_clear_message (); + RL_UNSETSTATE(RL_STATE_NUMERICARG); return 1; } rl_message ("(arg: %d) ", rl_arg_sign * rl_numeric_arg); + RL_SETSTATE(RL_STATE_MOREINPUT); key = c = rl_read_key (); + RL_UNSETSTATE(RL_STATE_MOREINPUT); + + if (c < 0) + { + _rl_abort_internal (); + return -1; + } /* If we see a key bound to `universal-argument' after seeing digits, it ends the argument but is otherwise ignored. */ @@ -878,9 +894,12 @@ rl_digit_loop () } else { + RL_SETSTATE(RL_STATE_MOREINPUT); key = rl_read_key (); + RL_UNSETSTATE(RL_STATE_MOREINPUT); rl_restore_prompt (); rl_clear_message (); + RL_UNSETSTATE(RL_STATE_NUMERICARG); return (_rl_dispatch (key, _rl_keymap)); } } @@ -904,11 +923,12 @@ rl_digit_loop () rl_explicit_arg = 1; rl_restore_prompt (); rl_clear_message (); + RL_UNSETSTATE(RL_STATE_NUMERICARG); return (_rl_dispatch (key, _rl_keymap)); } } - return 0; + /*NOTREACHED*/ } /* Add the current digit to the argument in progress. */ @@ -916,7 +936,7 @@ int rl_digit_argument (ignore, key) int ignore, key; { - rl_pending_input = key; + rl_execute_next (key); return (rl_digit_loop ()); } @@ -924,7 +944,7 @@ rl_digit_argument (ignore, key) int rl_discard_argument () { - ding (); + rl_ding (); rl_clear_message (); _rl_init_argument (); return 0; @@ -961,7 +981,7 @@ rl_universal_argument (count, key) function. */ int rl_insert_text (string) - char *string; + const char *string; { register int i, l = strlen (string); @@ -1054,7 +1074,7 @@ _rl_fix_point (fix_mark_too) void _rl_replace_text (text, start, end) - char *text; + const char *text; int start, end; { rl_begin_undo_group (); @@ -1108,7 +1128,7 @@ rl_forward (count, key) { int end = rl_point + count; #if defined (VI_MODE) - int lend = rl_end - (rl_editing_mode == vi_mode); + int lend = rl_end > 0 ? rl_end - (rl_editing_mode == vi_mode) : rl_end; #else int lend = rl_end; #endif @@ -1116,11 +1136,15 @@ rl_forward (count, key) if (end > lend) { rl_point = lend; - ding (); + rl_ding (); } else rl_point = end; } + + if (rl_end < 0) + rl_end = 0; + return 0; } @@ -1136,11 +1160,15 @@ rl_backward (count, key) if (rl_point < count) { rl_point = 0; - ding (); + rl_ding (); } else rl_point -= count; } + + if (rl_point < 0) + rl_point = 0; + return 0; } @@ -1183,12 +1211,12 @@ rl_forward_word (count, key) /* If we are not in a word, move forward until we are in one. Then, move forward until we hit a non-alphabetic character. */ c = the_line[rl_point]; - if (alphabetic (c) == 0) + if (rl_alphabetic (c) == 0) { while (++rl_point < rl_end) { c = the_line[rl_point]; - if (alphabetic (c)) + if (rl_alphabetic (c)) break; } } @@ -1197,7 +1225,7 @@ rl_forward_word (count, key) while (++rl_point < rl_end) { c = the_line[rl_point]; - if (alphabetic (c) == 0) + if (rl_alphabetic (c) == 0) break; } --count; @@ -1227,12 +1255,12 @@ rl_backward_word (count, key) just before point. */ c = the_line[rl_point - 1]; - if (alphabetic (c) == 0) + if (rl_alphabetic (c) == 0) { while (--rl_point) { c = the_line[rl_point - 1]; - if (alphabetic (c)) + if (rl_alphabetic (c)) break; } } @@ -1240,7 +1268,7 @@ rl_backward_word (count, key) while (rl_point) { c = the_line[rl_point - 1]; - if (alphabetic (c) == 0) + if (rl_alphabetic (c) == 0) break; else --rl_point; @@ -1255,35 +1283,14 @@ int rl_refresh_line (ignore1, ignore2) int ignore1, ignore2; { - int curr_line, nleft; + int curr_line; - /* Find out whether or not there might be invisible characters in the - editing buffer. */ - if (rl_display_prompt == rl_prompt) - nleft = _rl_last_c_pos - screenwidth - rl_visible_prompt_length; - else - nleft = _rl_last_c_pos - screenwidth; - - if (nleft > 0) - curr_line = 1 + nleft / screenwidth; - else - curr_line = 0; + curr_line = _rl_current_display_line (); _rl_move_vert (curr_line); _rl_move_cursor_relative (0, the_line); /* XXX is this right */ -#if defined (__GO32__) - { - int row, col, width, row_start; - - ScreenGetCursor (&row, &col); - width = ScreenCols (); - row_start = ScreenPrimary + (row * width); - memset (row_start + col, 0, (width - col) * 2); - } -#else /* !__GO32__ */ _rl_clear_to_eol (0); /* arg of 0 means to not use spaces */ -#endif /* !__GO32__ */ rl_forced_update_display (); rl_display_fixed = 1; @@ -1317,7 +1324,9 @@ rl_arrow_keys (count, c) { int ch; + RL_SETSTATE(RL_STATE_MOREINPUT); ch = rl_read_key (); + RL_UNSETSTATE(RL_STATE_MOREINPUT); switch (_rl_to_upper (ch)) { @@ -1338,7 +1347,7 @@ rl_arrow_keys (count, c) break; default: - ding (); + rl_ding (); } return 0; } @@ -1365,7 +1374,7 @@ rl_insert (count, c) readline because of extra large arguments. */ if (count > 1 && count <= 1024) { - string = xmalloc (1 + count); + string = (char *)xmalloc (1 + count); for (i = 0; i < count; i++) string[i] = c; @@ -1421,7 +1430,18 @@ rl_quoted_insert (count, key) { int c; +#if defined (HANDLE_SIGNALS) + _rl_disable_tty_signals (); +#endif + + RL_SETSTATE(RL_STATE_MOREINPUT); c = rl_read_key (); + RL_UNSETSTATE(RL_STATE_MOREINPUT); + +#if defined (HANDLE_SIGNALS) + _rl_restore_tty_signals (); +#endif + return (rl_insert (count, c)); } @@ -1442,6 +1462,11 @@ rl_newline (count, key) { rl_done = 1; + if (_rl_history_preserve_point) + _rl_history_saved_point = (rl_point == rl_end) ? -1 : rl_point; + + RL_SETSTATE(RL_STATE_DONE); + #if defined (VI_MODE) if (rl_editing_mode == vi_mode) { @@ -1451,7 +1476,7 @@ rl_newline (count, key) #endif /* VI_MODE */ /* If we've been asked to erase empty lines, suppress the final update, - since _rl_update_final calls crlf(). */ + since _rl_update_final calls rl_crlf(). */ if (rl_erase_empty_line && rl_point == 0 && rl_end == 0) return 0; @@ -1484,7 +1509,7 @@ rl_rubout (count, key) if (!rl_point) { - ding (); + rl_ding (); return -1; } @@ -1496,10 +1521,10 @@ rl_rubout (count, key) } else { - int c = the_line[--rl_point]; + unsigned char c = the_line[--rl_point]; rl_delete_text (rl_point, rl_point + 1); - if (rl_point == rl_end && isprint (c) && _rl_last_c_pos) + if (rl_point == rl_end && ISPRINT (c) && _rl_last_c_pos) { int l; l = rl_character_len (c, rl_point); @@ -1520,7 +1545,7 @@ rl_delete (count, key) if (rl_point == rl_end) { - ding (); + rl_ding (); return -1; } @@ -1615,8 +1640,6 @@ rl_insert_comment (count, key) #define DownCase 2 #define CapCase 3 -static int rl_change_case (); - /* Uppercase the word at point. */ int rl_upcase_word (count, key) @@ -1678,11 +1701,11 @@ rl_change_case (count, op) case CapCase: the_line[start] = (inword == 0) ? _rl_to_upper (c) : _rl_to_lower (c); - inword = alphabetic (the_line[start]); + inword = rl_alphabetic (the_line[start]); break; default: - ding (); + rl_ding (); return -1; } } @@ -1696,7 +1719,8 @@ rl_change_case (count, op) /* */ /* **************************************************************** */ -/* Transpose the words at point. */ +/* Transpose the words at point. If point is at the end of the line, + transpose the two words before point. */ int rl_transpose_words (count, key) int count, key; @@ -1721,7 +1745,7 @@ rl_transpose_words (count, key) /* Do some check to make sure that there really are two words. */ if ((w1_beg == w2_beg) || (w2_beg < w1_end)) { - ding (); + rl_ding (); rl_point = orig_point; return -1; } @@ -1769,7 +1793,7 @@ rl_transpose_chars (count, key) if (!rl_point || rl_end < 2) { - ding (); + rl_ding (); return -1; } @@ -1813,7 +1837,7 @@ _rl_char_search_internal (count, dir, schar) { if ((dir < 0 && pos <= 0) || (dir > 0 && pos >= rl_end)) { - ding (); + rl_ding (); return -1; } @@ -1844,7 +1868,10 @@ _rl_char_search (count, fdir, bdir) { int c; + RL_SETSTATE(RL_STATE_MOREINPUT); c = rl_read_key (); + RL_UNSETSTATE(RL_STATE_MOREINPUT); + if (count < 0) return (_rl_char_search_internal (-count, bdir, c)); else @@ -1877,17 +1904,17 @@ rl_backward_char_search (count, key) /* While we are editing the history, this is the saved version of the original line. */ -HIST_ENTRY *saved_line_for_history = (HIST_ENTRY *)NULL; +HIST_ENTRY *_rl_saved_line_for_history = (HIST_ENTRY *)NULL; /* Set the history pointer back to the last entry in the history. */ static void start_using_history () { using_history (); - if (saved_line_for_history) - _rl_free_history_entry (saved_line_for_history); + if (_rl_saved_line_for_history) + _rl_free_history_entry (_rl_saved_line_for_history); - saved_line_for_history = (HIST_ENTRY *)NULL; + _rl_saved_line_for_history = (HIST_ENTRY *)NULL; } /* Free the contents (and containing structure) of a HIST_ENTRY. */ @@ -1904,7 +1931,7 @@ _rl_free_history_entry (entry) /* Perhaps put back the current line if it has changed. */ int -maybe_replace_line () +rl_maybe_replace_line () { HIST_ENTRY *temp; @@ -1919,43 +1946,54 @@ maybe_replace_line () return 0; } -/* Put back the saved_line_for_history if there is one. */ +/* Restore the _rl_saved_line_for_history if there is one. */ int -maybe_unsave_line () +rl_maybe_unsave_line () { int line_len; - if (saved_line_for_history) + if (_rl_saved_line_for_history) { - line_len = strlen (saved_line_for_history->line); + line_len = strlen (_rl_saved_line_for_history->line); if (line_len >= rl_line_buffer_len) rl_extend_line_buffer (line_len); - strcpy (the_line, saved_line_for_history->line); - rl_undo_list = (UNDO_LIST *)saved_line_for_history->data; - _rl_free_history_entry (saved_line_for_history); - saved_line_for_history = (HIST_ENTRY *)NULL; + strcpy (the_line, _rl_saved_line_for_history->line); + rl_undo_list = (UNDO_LIST *)_rl_saved_line_for_history->data; + _rl_free_history_entry (_rl_saved_line_for_history); + _rl_saved_line_for_history = (HIST_ENTRY *)NULL; rl_end = rl_point = strlen (the_line); } else - ding (); + rl_ding (); return 0; } -/* Save the current line in saved_line_for_history. */ +/* Save the current line in _rl_saved_line_for_history. */ int -maybe_save_line () +rl_maybe_save_line () { - if (saved_line_for_history == 0) + if (_rl_saved_line_for_history == 0) { - saved_line_for_history = (HIST_ENTRY *)xmalloc (sizeof (HIST_ENTRY)); - saved_line_for_history->line = savestring (the_line); - saved_line_for_history->data = (char *)rl_undo_list; + _rl_saved_line_for_history = (HIST_ENTRY *)xmalloc (sizeof (HIST_ENTRY)); + _rl_saved_line_for_history->line = savestring (the_line); + _rl_saved_line_for_history->data = (char *)rl_undo_list; } return 0; } +int +_rl_free_saved_history_line () +{ + if (_rl_saved_line_for_history) + { + _rl_free_history_entry (_rl_saved_line_for_history); + _rl_saved_line_for_history = (HIST_ENTRY *)NULL; + } + return 0; +} + /* **************************************************************** */ /* */ /* History Commands */ @@ -1975,9 +2013,9 @@ int rl_end_of_history (count, key) int count, key; { - maybe_replace_line (); + rl_maybe_replace_line (); using_history (); - maybe_unsave_line (); + rl_maybe_unsave_line (); return 0; } @@ -1995,7 +2033,11 @@ rl_get_next_history (count, key) if (count == 0) return 0; - maybe_replace_line (); + rl_maybe_replace_line (); + + /* either not saved by rl_newline or at end of line, so set appropriately. */ + if (_rl_history_saved_point == -1 && (rl_point || rl_end)) + _rl_history_saved_point = (rl_point == rl_end) ? -1 : rl_point; temp = (HIST_ENTRY *)NULL; while (count) @@ -2007,7 +2049,7 @@ rl_get_next_history (count, key) } if (temp == 0) - maybe_unsave_line (); + rl_maybe_unsave_line (); else { line_len = strlen (temp->line); @@ -2017,7 +2059,12 @@ rl_get_next_history (count, key) strcpy (the_line, temp->line); rl_undo_list = (UNDO_LIST *)temp->data; - rl_end = rl_point = strlen (the_line); + rl_end = strlen (the_line); + rl_point = (_rl_history_preserve_point && _rl_history_saved_point != -1) + ? _rl_history_saved_point + : rl_end; + if (rl_point > rl_end) + rl_point = rl_end; #if defined (VI_MODE) if (rl_editing_mode == vi_mode) rl_point = 0; @@ -2041,11 +2088,15 @@ rl_get_previous_history (count, key) if (count == 0) return 0; + /* either not saved by rl_newline or at end of line, so set appropriately. */ + if (_rl_history_saved_point == -1 && (rl_point || rl_end)) + _rl_history_saved_point = (rl_point == rl_end) ? -1 : rl_point; + /* If we don't have a line saved, then save this one. */ - maybe_save_line (); + rl_maybe_save_line (); /* If the current line has changed, save the changes. */ - maybe_replace_line (); + rl_maybe_replace_line (); temp = old_temp = (HIST_ENTRY *)NULL; while (count) @@ -2064,7 +2115,7 @@ rl_get_previous_history (count, key) temp = old_temp; if (temp == 0) - ding (); + rl_ding (); else { line_len = strlen (temp->line); @@ -2074,7 +2125,12 @@ rl_get_previous_history (count, key) strcpy (the_line, temp->line); rl_undo_list = (UNDO_LIST *)temp->data; - rl_end = rl_point = line_len; + rl_end = line_len; + rl_point = (_rl_history_preserve_point && _rl_history_saved_point != -1) + ? _rl_history_saved_point + : rl_end; + if (rl_point > rl_end) + rl_point = rl_end; #if defined (VI_MODE) if (rl_editing_mode == vi_mode) @@ -2120,7 +2176,7 @@ rl_exchange_point_and_mark (count, key) if (rl_mark == -1) { - ding (); + rl_ding (); return -1; } else