📄 readline.c
字号:
static sighandlerrl_handle_sigwinch (sig) int sig;{ char *term; term = rl_terminal_name; if (readline_echoing_p) { if (!term) term = getenv ("TERM"); if (!term) term = "dumb"; rl_reset_terminal (term);#if defined (NOTDEF) crlf (); rl_forced_update_display ();#endif /* NOTDEF */ } if (old_sigwinch && old_sigwinch != (SigHandler *)SIG_IGN && old_sigwinch != (SigHandler *)SIG_DFL) (*old_sigwinch) (sig);#if !defined (VOID_SIGHANDLER) return (0);#endif /* VOID_SIGHANDLER */}#endif /* SIGWINCH */#if defined (HANDLE_SIGNALS)/* Interrupt handling. */static SigHandler *old_int = (SigHandler *)NULL, *old_tstp = (SigHandler *)NULL, *old_ttou = (SigHandler *)NULL, *old_ttin = (SigHandler *)NULL, *old_cont = (SigHandler *)NULL, *old_alrm = (SigHandler *)NULL;/* Handle an interrupt character. */static sighandlerrl_signal_handler (sig) int sig;{#if !defined (HAVE_BSD_SIGNALS) /* Since the signal will not be blocked while we are in the signal handler, ignore it until rl_clear_signals resets the catcher. */ if (sig == SIGINT) signal (sig, SIG_IGN);#endif /* !HAVE_BSD_SIGNALS */ switch (sig) { case SIGINT: free_undo_list (); rl_clear_message (); rl_init_argument ();#if defined (SIGTSTP) case SIGTSTP: case SIGTTOU: case SIGTTIN:#endif /* SIGTSTP */ case SIGALRM: rl_clean_up_for_exit (); rl_deprep_terminal (); rl_clear_signals (); rl_pending_input = 0; kill (getpid (), sig); SIGNALS_UNBLOCK; rl_prep_terminal (); rl_set_signals (); }#if !defined (VOID_SIGHANDLER) return (0);#endif /* !VOID_SIGHANDLER */}rl_set_signals (){ old_int = (SigHandler *)signal (SIGINT, rl_signal_handler); if (old_int == (SigHandler *)SIG_IGN) signal (SIGINT, SIG_IGN); old_alrm = (SigHandler *)signal (SIGALRM, rl_signal_handler); if (old_alrm == (SigHandler *)SIG_IGN) signal (SIGALRM, SIG_IGN);#if defined (SIGTSTP) old_tstp = (SigHandler *)signal (SIGTSTP, rl_signal_handler); if (old_tstp == (SigHandler *)SIG_IGN) signal (SIGTSTP, SIG_IGN);#endif#if defined (SIGTTOU) old_ttou = (SigHandler *)signal (SIGTTOU, rl_signal_handler); old_ttin = (SigHandler *)signal (SIGTTIN, rl_signal_handler); if (old_tstp == (SigHandler *)SIG_IGN) { signal (SIGTTOU, SIG_IGN); signal (SIGTTIN, SIG_IGN); }#endif#if defined (SIGWINCH) old_sigwinch = (SigHandler *)signal (SIGWINCH, rl_handle_sigwinch);#endif}rl_clear_signals (){ signal (SIGINT, old_int); signal (SIGALRM, old_alrm);#if defined (SIGTSTP) signal (SIGTSTP, old_tstp);#endif#if defined (SIGTTOU) signal (SIGTTOU, old_ttou); signal (SIGTTIN, old_ttin);#endif#if defined (SIGWINCH) signal (SIGWINCH, old_sigwinch);#endif}#endif /* HANDLE_SIGNALS *//* **************************************************************** *//* *//* Character Input Buffering *//* *//* **************************************************************** */#if defined (USE_XON_XOFF)/* If the terminal was in xoff state when we got to it, then xon_char contains the character that is supposed to start it again. */static int xon_char, xoff_state;#endif /* USE_XON_XOFF */static int pop_index = 0, push_index = 0, ibuffer_len = 511;static unsigned char ibuffer[512];/* Non-null means it is a pointer to a function to run while waiting for character input. */Function *rl_event_hook = (Function *)NULL;#define any_typein (push_index != pop_index)/* Add KEY to the buffer of characters to be read. */rl_stuff_char (key) int key;{ if (key == EOF) { key = NEWLINE; rl_pending_input = EOF; } ibuffer[push_index++] = key; if (push_index >= ibuffer_len) push_index = 0;}/* Return the amount of space available in the buffer for stuffing characters. */intibuffer_space (){ if (pop_index > push_index) return (pop_index - push_index); else return (ibuffer_len - (push_index - pop_index));}/* Get a key from the buffer of characters to be read. Return the key in KEY. Result is KEY if there was a key, or 0 if there wasn't. */intrl_get_char (key) int *key;{ if (push_index == pop_index) return (0); *key = ibuffer[pop_index++]; if (pop_index >= ibuffer_len) pop_index = 0; return (1);}/* Stuff KEY into the *front* of the input buffer. Returns non-zero if successful, zero if there is no space left in the buffer. */intrl_unget_char (key) int key;{ if (ibuffer_space ()) { pop_index--; if (pop_index < 0) pop_index = ibuffer_len - 1; ibuffer[pop_index] = key; return (1); } return (0);}/* If a character is available to be read, then read it and stuff it into IBUFFER. Otherwise, just return. */rl_gather_tyi (){#ifdef __GO32__ char input; if (isatty(0)) { int i = rl_getc(); if (i != EOF) rl_stuff_char(i); } else if (kbhit() && ibuffer_space()) rl_stuff_char(getkey());#else int tty = fileno (in_stream); register int tem, result = -1; long chars_avail; char input;#if defined (FIONREAD) result = ioctl (tty, FIONREAD, &chars_avail);#endif if (result == -1) { int flags; flags = fcntl (tty, F_GETFL, 0); fcntl (tty, F_SETFL, (flags | O_NDELAY)); chars_avail = read (tty, &input, 1); fcntl (tty, F_SETFL, flags); if (chars_avail == -1 && errno == EAGAIN) return; } /* If there's nothing available, don't waste time trying to read something. */ if (chars_avail == 0) return; tem = ibuffer_space (); if (chars_avail > tem) chars_avail = tem; /* One cannot read all of the available input. I can only read a single character at a time, or else programs which require input can be thwarted. If the buffer is larger than one character, I lose. Damn! */ if (tem < ibuffer_len) chars_avail = 0; if (result != -1) { while (chars_avail--) rl_stuff_char (rl_getc (in_stream)); } else { if (chars_avail) rl_stuff_char (input); }#endif /* def __GO32__/else */}static int next_macro_key ();/* Read a key, including pending input. */intrl_read_key (){ int c; rl_key_sequence_length++; if (rl_pending_input) { c = rl_pending_input; rl_pending_input = 0; } else { /* If input is coming from a macro, then use that. */ if (c = next_macro_key ()) return (c); /* If the user has an event function, then call it periodically. */ if (rl_event_hook) { while (rl_event_hook && !rl_get_char (&c)) { (*rl_event_hook) (); rl_gather_tyi (); } } else { if (!rl_get_char (&c)) c = rl_getc (in_stream); } } return (c);}/* I'm beginning to hate the declaration rules for various compilers. */static void add_macro_char (), with_macro_input ();/* Do the command associated with KEY in MAP. If the associated command is really a keymap, then read another key, and dispatch into that map. */rl_dispatch (key, map) register int key; Keymap map;{ if (defining_kbd_macro) add_macro_char (key); if (key > 127 && key < 256) { if (map[ESC].type == ISKMAP) { map = (Keymap)map[ESC].function; key -= 128; rl_dispatch (key, map); } else ding (); return; } switch (map[key].type) { case ISFUNC: { Function *func = map[key].function; if (func != (Function *)NULL) { /* Special case rl_do_lowercase_version (). */ if (func == rl_do_lowercase_version) { rl_dispatch (to_lower (key), map); return; } (*map[key].function)(rl_numeric_arg * rl_arg_sign, key); /* 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) rl_last_func = map[key].function; } else { rl_abort (); return; } } break; case ISKMAP: if (map[key].function != (Function *)NULL) { int newkey; rl_key_sequence_length++; newkey = rl_read_key (); rl_dispatch (newkey, (Keymap)map[key].function); } else { rl_abort (); return; } break; case ISMACR: if (map[key].function != (Function *)NULL) { char *macro; macro = savestring ((char *)map[key].function); with_macro_input (macro); return; } break; }}/* **************************************************************** *//* *//* Hacking Keyboard Macros *//* *//* **************************************************************** *//* The currently executing macro string. If this is non-zero, then it is a malloc ()'ed string where input is coming from. */static char *executing_macro = (char *)NULL;/* The offset in the above string to the next character to be read. */static int executing_macro_index = 0;/* The current macro string being built. Characters get stuffed in here by add_macro_char (). */static char *current_macro = (char *)NULL;/* The size of the buffer allocated to current_macro. */static int current_macro_size = 0;/* The index at which characters are being added to current_macro. */static int current_macro_index = 0;/* A structure used to save nested macro strings. It is a linked list of string/index for each saved macro. */struct saved_macro { struct saved_macro *next; char *string; int index;};/* The list of saved macros. */struct saved_macro *macro_list = (struct saved_macro *)NULL;/* Forward declarations of static functions. Thank you C. */static void push_executing_macro (), pop_executing_macro ();/* This one has to be declared earlier in the file. *//* static void add_macro_char (); *//* Set up to read subsequent input from STRING. STRING is free ()'ed when we are done with it. */static voidwith_macro_input (string) char *string;{ push_executing_macro (); executing_macro = string; executing_macro_index = 0;}/* Return the next character available from a macro, or 0 if there are no macro characters. */static intnext_macro_key (){ if (!executing_macro) return (0); if (!executing_macro[executing_macro_index]) { pop_executing_macro (); return (next_macro_key ()); } return (executing_macro[executing_macro_index++]);}/* Save the currently executing macro on a stack of saved macros. */static voidpush_executing_macro (){ struct saved_macro *saver; saver = (struct saved_macro *)xmalloc (sizeof (struct saved_macro)); saver->next = macro_list; saver->index = executing_macro_index; saver->string = executing_macro; macro_list = saver;}/* Discard the current macro, replacing it with the one on the top of the stack of saved macros. */static voidpop_executing_macro (){ if (executing_macro) free (executing_macro); executing_macro = (char *)NULL; executing_macro_index = 0; if (macro_list) { struct saved_macro *disposer = macro_list; executing_macro = macro_list->string; executing_macro_index = macro_list->index; macro_list = macro_list->next; free (disposer); }}/* Add a character to the macro being built. */static voidadd_macro_char (c) int c;{ if (current_macro_index + 1 >= current_macro_size) { if (!current_macro) current_macro = (char *)xmalloc (current_macro_size = 25); else current_macro = (char *)xrealloc (current_macro, current_macro_size += 25); } current_macro[current_macro_index++] = c; current_macro[current_macro_index] = '\0';}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -