1: /* callback.c -- functions to use readline as an X `callback' mechanism. */
2:
3: /* Copyright (C) 1987-2017 Free Software Foundation, Inc.
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:
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:
61: /* **************************************************************** */
62: /* */
63: /* Callback Readline Functions */
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
83: _rl_callback_newline (void)
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);
93:
94: #if defined (HANDLE_SIGNALS)
95: if (rl_persistent_signal_handlers)
96: rl_set_signals ();
97: #endif
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
106: rl_callback_handler_install (const char *prompt, rl_vcpfunc_t *linefunc)
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 { \
117: if (rl_persistent_signal_handlers == 0) \
118: rl_clear_signals (); \
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
127: rl_callback_read_char (void)
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. */
155: if (rl_persistent_signal_handlers == 0)
156: rl_set_signals ();
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)
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: }
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
300: rl_callback_handler_remove (void)
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 *
317: _rl_callback_data_alloc (int count)
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:
329: void
330: _rl_callback_data_dispose (_rl_callback_generic_arg *arg)
331: {
332: xfree (arg);
333: }
334:
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: }
360: #endif
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>