Commit | Line | Data |
---|---|---|
d60d9f65 SS |
1 | /* callback.c -- functions to use readline as an X `callback' mechanism. */ |
2 | ||
cb41b9e7 | 3 | /* Copyright (C) 1987-2017 Free Software Foundation, Inc. |
d60d9f65 | 4 | |
cc88a640 JK |
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. | |
d60d9f65 | 7 | |
cc88a640 JK |
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 | |
d60d9f65 SS |
11 | (at your option) any later version. |
12 | ||
cc88a640 JK |
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 | |
d60d9f65 SS |
16 | GNU General Public License for more details. |
17 | ||
cc88a640 JK |
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 | ||
d60d9f65 SS |
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> | |
9255ee31 EZ |
33 | |
34 | #ifdef HAVE_STDLIB_H | |
35 | # include <stdlib.h> | |
36 | #else | |
37 | # include "ansi_stdlib.h" | |
38 | #endif | |
39 | ||
d60d9f65 SS |
40 | #include <stdio.h> |
41 | ||
42 | /* System-specific feature definitions and include files. */ | |
43 | #include "rldefs.h" | |
44 | #include "readline.h" | |
1b17e766 | 45 | #include "rlprivate.h" |
0b7b5a97 | 46 | #include "xmalloc.h" |
d60d9f65 | 47 | |
5bdf8622 DJ |
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 | ||
775e241e TT |
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 | ||
d60d9f65 SS |
61 | /* **************************************************************** */ |
62 | /* */ | |
cb41b9e7 | 63 | /* Callback Readline Functions */ |
d60d9f65 SS |
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 | |
775e241e TT |
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. */ | |
d60d9f65 | 77 | |
9255ee31 | 78 | rl_vcpfunc_t *rl_linefunc; /* user callback function */ |
d60d9f65 SS |
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 | |
cb41b9e7 | 83 | _rl_callback_newline (void) |
d60d9f65 SS |
84 | { |
85 | rl_initialize (); | |
86 | ||
87 | if (in_handler == 0) | |
88 | { | |
89 | in_handler = 1; | |
90 | ||
5bdf8622 DJ |
91 | if (rl_prep_term_function) |
92 | (*rl_prep_term_function) (_rl_meta_flag); | |
5836a818 PP |
93 | |
94 | #if defined (HANDLE_SIGNALS) | |
775e241e TT |
95 | if (rl_persistent_signal_handlers) |
96 | rl_set_signals (); | |
5836a818 | 97 | #endif |
d60d9f65 SS |
98 | } |
99 | ||
100 | readline_internal_setup (); | |
cc88a640 | 101 | RL_CHECK_SIGNALS (); |
d60d9f65 SS |
102 | } |
103 | ||
104 | /* Install a readline handler, set up the terminal, and issue the prompt. */ | |
105 | void | |
cb41b9e7 | 106 | rl_callback_handler_install (const char *prompt, rl_vcpfunc_t *linefunc) |
d60d9f65 | 107 | { |
9255ee31 | 108 | rl_set_prompt (prompt); |
5bdf8622 | 109 | RL_SETSTATE (RL_STATE_CALLBACK); |
d60d9f65 SS |
110 | rl_linefunc = linefunc; |
111 | _rl_callback_newline (); | |
112 | } | |
113 | ||
775e241e TT |
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 | ||
d60d9f65 SS |
125 | /* Read one character, and dispatch to the handler if it ends the line. */ |
126 | void | |
cb41b9e7 | 127 | rl_callback_read_char (void) |
d60d9f65 SS |
128 | { |
129 | char *line; | |
5bdf8622 DJ |
130 | int eof, jcode; |
131 | static procenv_t olevel; | |
d60d9f65 SS |
132 | |
133 | if (rl_linefunc == NULL) | |
134 | { | |
cc88a640 | 135 | _rl_errmsg ("readline_callback_read_char() called with no handler!"); |
d60d9f65 SS |
136 | abort (); |
137 | } | |
138 | ||
cc88a640 | 139 | memcpy ((void *)olevel, (void *)_rl_top_level, sizeof (procenv_t)); |
775e241e TT |
140 | #if defined (HAVE_POSIX_SIGSETJMP) |
141 | jcode = sigsetjmp (_rl_top_level, 0); | |
142 | #else | |
cc88a640 | 143 | jcode = setjmp (_rl_top_level); |
775e241e | 144 | #endif |
5bdf8622 DJ |
145 | if (jcode) |
146 | { | |
147 | (*rl_redisplay_function) (); | |
148 | _rl_want_redisplay = 0; | |
cc88a640 | 149 | memcpy ((void *)_rl_top_level, (void *)olevel, sizeof (procenv_t)); |
775e241e | 150 | CALLBACK_READ_RETURN (); |
5bdf8622 DJ |
151 | } |
152 | ||
775e241e TT |
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 | ||
cc88a640 | 159 | do |
5bdf8622 | 160 | { |
cc88a640 JK |
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 (); | |
5bdf8622 | 167 | |
775e241e | 168 | CALLBACK_READ_RETURN (); |
cc88a640 JK |
169 | } |
170 | else if (RL_ISSTATE (RL_STATE_NSEARCH)) | |
171 | { | |
172 | eof = _rl_nsearch_callback (_rl_nscxt); | |
775e241e TT |
173 | |
174 | CALLBACK_READ_RETURN (); | |
cc88a640 JK |
175 | } |
176 | #if defined (VI_MODE) | |
775e241e TT |
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 | } | |
cc88a640 JK |
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 (); | |
5bdf8622 | 214 | |
775e241e | 215 | CALLBACK_READ_RETURN (); |
cc88a640 JK |
216 | } |
217 | #endif | |
218 | else if (RL_ISSTATE (RL_STATE_NUMERICARG)) | |
5bdf8622 | 219 | { |
cc88a640 JK |
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 | ||
775e241e | 227 | CALLBACK_READ_RETURN (); |
5bdf8622 | 228 | } |
cc88a640 | 229 | else if (RL_ISSTATE (RL_STATE_MULTIKEY)) |
5bdf8622 | 230 | { |
cc88a640 JK |
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) | |
5bdf8622 | 235 | { |
cc88a640 JK |
236 | _rl_internal_char_cleanup (); |
237 | _rl_want_redisplay = 1; | |
5bdf8622 | 238 | } |
5bdf8622 | 239 | } |
cc88a640 JK |
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 | |
775e241e | 244 | called when input is available. _rl_callback_data is a |
cc88a640 JK |
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 (); | |
5bdf8622 | 263 | |
cc88a640 JK |
264 | RL_CHECK_SIGNALS (); |
265 | if (rl_done == 0 && _rl_want_redisplay) | |
266 | { | |
267 | (*rl_redisplay_function) (); | |
268 | _rl_want_redisplay = 0; | |
269 | } | |
d60d9f65 | 270 | |
9255ee31 EZ |
271 | if (rl_done) |
272 | { | |
273 | line = readline_internal_teardown (eof); | |
d60d9f65 | 274 | |
5bdf8622 DJ |
275 | if (rl_deprep_term_function) |
276 | (*rl_deprep_term_function) (); | |
d60d9f65 | 277 | #if defined (HANDLE_SIGNALS) |
9255ee31 | 278 | rl_clear_signals (); |
d60d9f65 | 279 | #endif |
9255ee31 EZ |
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 | } | |
d60d9f65 | 292 | } |
cc88a640 | 293 | while (rl_pending_input || _rl_pushed_input_available () || RL_ISSTATE (RL_STATE_MACROINPUT)); |
775e241e TT |
294 | |
295 | CALLBACK_READ_RETURN (); | |
d60d9f65 SS |
296 | } |
297 | ||
298 | /* Remove the handler, and make sure the terminal is in its normal state. */ | |
299 | void | |
cb41b9e7 | 300 | rl_callback_handler_remove (void) |
d60d9f65 SS |
301 | { |
302 | rl_linefunc = NULL; | |
5bdf8622 | 303 | RL_UNSETSTATE (RL_STATE_CALLBACK); |
cc88a640 | 304 | RL_CHECK_SIGNALS (); |
d60d9f65 SS |
305 | if (in_handler) |
306 | { | |
307 | in_handler = 0; | |
5bdf8622 DJ |
308 | if (rl_deprep_term_function) |
309 | (*rl_deprep_term_function) (); | |
d60d9f65 SS |
310 | #if defined (HANDLE_SIGNALS) |
311 | rl_clear_signals (); | |
312 | #endif | |
313 | } | |
314 | } | |
315 | ||
5bdf8622 | 316 | _rl_callback_generic_arg * |
cb41b9e7 | 317 | _rl_callback_data_alloc (int count) |
5bdf8622 DJ |
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 | ||
775e241e | 329 | void |
cb41b9e7 | 330 | _rl_callback_data_dispose (_rl_callback_generic_arg *arg) |
5bdf8622 | 331 | { |
cc88a640 | 332 | xfree (arg); |
5bdf8622 DJ |
333 | } |
334 | ||
775e241e TT |
335 | /* Make sure that this agrees with cases in rl_callback_read_char */ |
336 | void | |
cb41b9e7 | 337 | rl_callback_sigcleanup (void) |
775e241e TT |
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 | } | |
d60d9f65 | 360 | #endif |