Annotation of embedaddon/readline/callback.c, revision 1.1.1.2
1.1 misho 1: /* callback.c -- functions to use readline as an X `callback' mechanism. */
2:
1.1.1.2 ! misho 3: /* Copyright (C) 1987-2017 Free Software Foundation, Inc.
1.1 misho 4:
5: This file is part of the GNU Readline Library (Readline), a library
6: for reading lines of text with interactive input and history editing.
7:
8: Readline is free software: you can redistribute it and/or modify
9: it under the terms of the GNU General Public License as published by
10: the Free Software Foundation, either version 3 of the License, or
11: (at your option) any later version.
12:
13: Readline is distributed in the hope that it will be useful,
14: but WITHOUT ANY WARRANTY; without even the implied warranty of
15: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16: GNU General Public License for more details.
17:
18: You should have received a copy of the GNU General Public License
19: along with Readline. If not, see <http://www.gnu.org/licenses/>.
20: */
21:
22: #define READLINE_LIBRARY
23:
24: #if defined (HAVE_CONFIG_H)
25: # include <config.h>
26: #endif
27:
28: #include "rlconf.h"
29:
30: #if defined (READLINE_CALLBACKS)
31:
32: #include <sys/types.h>
33:
34: #ifdef HAVE_STDLIB_H
35: # include <stdlib.h>
36: #else
37: # include "ansi_stdlib.h"
38: #endif
39:
40: #include <stdio.h>
41:
42: /* System-specific feature definitions and include files. */
43: #include "rldefs.h"
44: #include "readline.h"
45: #include "rlprivate.h"
46: #include "xmalloc.h"
47:
48: /* Private data for callback registration functions. See comments in
49: rl_callback_read_char for more details. */
50: _rl_callback_func_t *_rl_callback_func = 0;
51: _rl_callback_generic_arg *_rl_callback_data = 0;
52:
1.1.1.2 ! misho 53: /* Applications can set this to non-zero to have readline's signal handlers
! 54: installed during the entire duration of reading a complete line, as in
! 55: readline-6.2. This should be used with care, because it can result in
! 56: readline receiving signals and not handling them until it's called again
! 57: via rl_callback_read_char, thereby stealing them from the application.
! 58: By default, signal handlers are only active while readline is active. */
! 59: int rl_persistent_signal_handlers = 0;
! 60:
1.1 misho 61: /* **************************************************************** */
62: /* */
1.1.1.2 ! misho 63: /* Callback Readline Functions */
1.1 misho 64: /* */
65: /* **************************************************************** */
66:
67: /* Allow using readline in situations where a program may have multiple
68: things to handle at once, and dispatches them via select(). Call
69: rl_callback_handler_install() with the prompt and a function to call
70: whenever a complete line of input is ready. The user must then
71: call rl_callback_read_char() every time some input is available, and
72: rl_callback_read_char() will call the user's function with the complete
73: text read in at each end of line. The terminal is kept prepped
74: all the time, except during calls to the user's function. Signal
75: handlers are only installed when the application calls back into
76: readline, so readline doesn't `steal' signals from the application. */
77:
78: rl_vcpfunc_t *rl_linefunc; /* user callback function */
79: static int in_handler; /* terminal_prepped and signals set? */
80:
81: /* Make sure the terminal is set up, initialize readline, and prompt. */
82: static void
1.1.1.2 ! misho 83: _rl_callback_newline (void)
1.1 misho 84: {
85: rl_initialize ();
86:
87: if (in_handler == 0)
88: {
89: in_handler = 1;
90:
91: if (rl_prep_term_function)
92: (*rl_prep_term_function) (_rl_meta_flag);
1.1.1.2 ! misho 93:
! 94: #if defined (HANDLE_SIGNALS)
! 95: if (rl_persistent_signal_handlers)
! 96: rl_set_signals ();
! 97: #endif
1.1 misho 98: }
99:
100: readline_internal_setup ();
101: RL_CHECK_SIGNALS ();
102: }
103:
104: /* Install a readline handler, set up the terminal, and issue the prompt. */
105: void
1.1.1.2 ! misho 106: rl_callback_handler_install (const char *prompt, rl_vcpfunc_t *linefunc)
1.1 misho 107: {
108: rl_set_prompt (prompt);
109: RL_SETSTATE (RL_STATE_CALLBACK);
110: rl_linefunc = linefunc;
111: _rl_callback_newline ();
112: }
113:
114: #if defined (HANDLE_SIGNALS)
115: #define CALLBACK_READ_RETURN() \
116: do { \
1.1.1.2 ! misho 117: if (rl_persistent_signal_handlers == 0) \
! 118: rl_clear_signals (); \
1.1 misho 119: return; \
120: } while (0)
121: #else
122: #define CALLBACK_READ_RETURN() return
123: #endif
124:
125: /* Read one character, and dispatch to the handler if it ends the line. */
126: void
1.1.1.2 ! misho 127: rl_callback_read_char (void)
1.1 misho 128: {
129: char *line;
130: int eof, jcode;
131: static procenv_t olevel;
132:
133: if (rl_linefunc == NULL)
134: {
135: _rl_errmsg ("readline_callback_read_char() called with no handler!");
136: abort ();
137: }
138:
139: memcpy ((void *)olevel, (void *)_rl_top_level, sizeof (procenv_t));
140: #if defined (HAVE_POSIX_SIGSETJMP)
141: jcode = sigsetjmp (_rl_top_level, 0);
142: #else
143: jcode = setjmp (_rl_top_level);
144: #endif
145: if (jcode)
146: {
147: (*rl_redisplay_function) ();
148: _rl_want_redisplay = 0;
149: memcpy ((void *)_rl_top_level, (void *)olevel, sizeof (procenv_t));
150: CALLBACK_READ_RETURN ();
151: }
152:
153: #if defined (HANDLE_SIGNALS)
154: /* Install signal handlers only when readline has control. */
1.1.1.2 ! misho 155: if (rl_persistent_signal_handlers == 0)
! 156: rl_set_signals ();
1.1 misho 157: #endif
158:
159: do
160: {
161: RL_CHECK_SIGNALS ();
162: if (RL_ISSTATE (RL_STATE_ISEARCH))
163: {
164: eof = _rl_isearch_callback (_rl_iscxt);
165: if (eof == 0 && (RL_ISSTATE (RL_STATE_ISEARCH) == 0) && RL_ISSTATE (RL_STATE_INPUTPENDING))
166: rl_callback_read_char ();
167:
168: CALLBACK_READ_RETURN ();
169: }
170: else if (RL_ISSTATE (RL_STATE_NSEARCH))
171: {
172: eof = _rl_nsearch_callback (_rl_nscxt);
173:
174: CALLBACK_READ_RETURN ();
175: }
176: #if defined (VI_MODE)
1.1.1.2 ! misho 177: /* States that can occur while in state VIMOTION have to be checked
! 178: before RL_STATE_VIMOTION */
! 179: else if (RL_ISSTATE (RL_STATE_CHARSEARCH))
! 180: {
! 181: int k;
! 182:
! 183: k = _rl_callback_data->i2;
! 184:
! 185: eof = (*_rl_callback_func) (_rl_callback_data);
! 186: /* If the function `deregisters' itself, make sure the data is
! 187: cleaned up. */
! 188: if (_rl_callback_func == 0) /* XXX - just sanity check */
! 189: {
! 190: if (_rl_callback_data)
! 191: {
! 192: _rl_callback_data_dispose (_rl_callback_data);
! 193: _rl_callback_data = 0;
! 194: }
! 195: }
! 196:
! 197: /* Messy case where vi motion command can be char search */
! 198: if (RL_ISSTATE (RL_STATE_VIMOTION))
! 199: {
! 200: _rl_vi_domove_motion_cleanup (k, _rl_vimvcxt);
! 201: _rl_internal_char_cleanup ();
! 202: CALLBACK_READ_RETURN ();
! 203: }
! 204:
! 205: _rl_internal_char_cleanup ();
! 206: }
1.1 misho 207: else if (RL_ISSTATE (RL_STATE_VIMOTION))
208: {
209: eof = _rl_vi_domove_callback (_rl_vimvcxt);
210: /* Should handle everything, including cleanup, numeric arguments,
211: and turning off RL_STATE_VIMOTION */
212: if (RL_ISSTATE (RL_STATE_NUMERICARG) == 0)
213: _rl_internal_char_cleanup ();
214:
215: CALLBACK_READ_RETURN ();
216: }
217: #endif
218: else if (RL_ISSTATE (RL_STATE_NUMERICARG))
219: {
220: eof = _rl_arg_callback (_rl_argcxt);
221: if (eof == 0 && (RL_ISSTATE (RL_STATE_NUMERICARG) == 0) && RL_ISSTATE (RL_STATE_INPUTPENDING))
222: rl_callback_read_char ();
223: /* XXX - this should handle _rl_last_command_was_kill better */
224: else if (RL_ISSTATE (RL_STATE_NUMERICARG) == 0)
225: _rl_internal_char_cleanup ();
226:
227: CALLBACK_READ_RETURN ();
228: }
229: else if (RL_ISSTATE (RL_STATE_MULTIKEY))
230: {
231: eof = _rl_dispatch_callback (_rl_kscxt); /* For now */
232: while ((eof == -1 || eof == -2) && RL_ISSTATE (RL_STATE_MULTIKEY) && _rl_kscxt && (_rl_kscxt->flags & KSEQ_DISPATCHED))
233: eof = _rl_dispatch_callback (_rl_kscxt);
234: if (RL_ISSTATE (RL_STATE_MULTIKEY) == 0)
235: {
236: _rl_internal_char_cleanup ();
237: _rl_want_redisplay = 1;
238: }
239: }
240: else if (_rl_callback_func)
241: {
242: /* This allows functions that simply need to read an additional
243: character (like quoted-insert) to register a function to be
244: called when input is available. _rl_callback_data is a
245: pointer to a struct that has the argument count originally
246: passed to the registering function and space for any additional
247: parameters. */
248: eof = (*_rl_callback_func) (_rl_callback_data);
249: /* If the function `deregisters' itself, make sure the data is
250: cleaned up. */
251: if (_rl_callback_func == 0)
252: {
253: if (_rl_callback_data)
254: {
255: _rl_callback_data_dispose (_rl_callback_data);
256: _rl_callback_data = 0;
257: }
258: _rl_internal_char_cleanup ();
259: }
260: }
261: else
262: eof = readline_internal_char ();
263:
264: RL_CHECK_SIGNALS ();
265: if (rl_done == 0 && _rl_want_redisplay)
266: {
267: (*rl_redisplay_function) ();
268: _rl_want_redisplay = 0;
269: }
270:
271: if (rl_done)
272: {
273: line = readline_internal_teardown (eof);
274:
275: if (rl_deprep_term_function)
276: (*rl_deprep_term_function) ();
277: #if defined (HANDLE_SIGNALS)
278: rl_clear_signals ();
279: #endif
280: in_handler = 0;
281: (*rl_linefunc) (line);
282:
283: /* If the user did not clear out the line, do it for him. */
284: if (rl_line_buffer[0])
285: _rl_init_line_state ();
286:
287: /* Redisplay the prompt if readline_handler_{install,remove}
288: not called. */
289: if (in_handler == 0 && rl_linefunc)
290: _rl_callback_newline ();
291: }
292: }
293: while (rl_pending_input || _rl_pushed_input_available () || RL_ISSTATE (RL_STATE_MACROINPUT));
294:
295: CALLBACK_READ_RETURN ();
296: }
297:
298: /* Remove the handler, and make sure the terminal is in its normal state. */
299: void
1.1.1.2 ! misho 300: rl_callback_handler_remove (void)
1.1 misho 301: {
302: rl_linefunc = NULL;
303: RL_UNSETSTATE (RL_STATE_CALLBACK);
304: RL_CHECK_SIGNALS ();
305: if (in_handler)
306: {
307: in_handler = 0;
308: if (rl_deprep_term_function)
309: (*rl_deprep_term_function) ();
310: #if defined (HANDLE_SIGNALS)
311: rl_clear_signals ();
312: #endif
313: }
314: }
315:
316: _rl_callback_generic_arg *
1.1.1.2 ! misho 317: _rl_callback_data_alloc (int count)
1.1 misho 318: {
319: _rl_callback_generic_arg *arg;
320:
321: arg = (_rl_callback_generic_arg *)xmalloc (sizeof (_rl_callback_generic_arg));
322: arg->count = count;
323:
324: arg->i1 = arg->i2 = 0;
325:
326: return arg;
327: }
328:
1.1.1.2 ! misho 329: void
! 330: _rl_callback_data_dispose (_rl_callback_generic_arg *arg)
1.1 misho 331: {
332: xfree (arg);
333: }
334:
1.1.1.2 ! misho 335: /* Make sure that this agrees with cases in rl_callback_read_char */
! 336: void
! 337: rl_callback_sigcleanup (void)
! 338: {
! 339: if (RL_ISSTATE (RL_STATE_CALLBACK) == 0)
! 340: return;
! 341:
! 342: if (RL_ISSTATE (RL_STATE_ISEARCH))
! 343: _rl_isearch_cleanup (_rl_iscxt, 0);
! 344: else if (RL_ISSTATE (RL_STATE_NSEARCH))
! 345: _rl_nsearch_cleanup (_rl_nscxt, 0);
! 346: else if (RL_ISSTATE (RL_STATE_VIMOTION))
! 347: RL_UNSETSTATE (RL_STATE_VIMOTION);
! 348: else if (RL_ISSTATE (RL_STATE_NUMERICARG))
! 349: {
! 350: _rl_argcxt = 0;
! 351: RL_UNSETSTATE (RL_STATE_NUMERICARG);
! 352: }
! 353: else if (RL_ISSTATE (RL_STATE_MULTIKEY))
! 354: RL_UNSETSTATE (RL_STATE_MULTIKEY);
! 355: if (RL_ISSTATE (RL_STATE_CHARSEARCH))
! 356: RL_UNSETSTATE (RL_STATE_CHARSEARCH);
! 357:
! 358: _rl_callback_func = 0;
! 359: }
1.1 misho 360: #endif
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>