]>
Commit | Line | Data |
---|---|---|
ccc6cda3 JA |
1 | /* callback.c -- functions to use readline as an X `callback' mechanism. */ |
2 | ||
95732b49 | 3 | /* Copyright (C) 1987-2005 Free Software Foundation, Inc. |
ccc6cda3 JA |
4 | |
5 | This file is part of the GNU Readline Library, a library for | |
6 | reading lines of text with interactive input and history editing. | |
7 | ||
8 | The GNU Readline Library is free software; you can redistribute it | |
9 | and/or modify it under the terms of the GNU General Public License | |
bb70624e | 10 | as published by the Free Software Foundation; either version 2, or |
ccc6cda3 JA |
11 | (at your option) any later version. |
12 | ||
13 | The GNU Readline Library is distributed in the hope that it will be | |
14 | useful, but WITHOUT ANY WARRANTY; without even the implied warranty | |
15 | of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
16 | GNU General Public License for more details. | |
17 | ||
18 | The GNU General Public License is often shipped with GNU software, and | |
19 | is generally kept in a file called COPYING or LICENSE. If you do not | |
20 | have a copy of the license, write to the Free Software Foundation, | |
bb70624e | 21 | 59 Temple Place, Suite 330, Boston, MA 02111 USA. */ |
ccc6cda3 JA |
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> | |
f73dda09 JA |
33 | |
34 | #ifdef HAVE_STDLIB_H | |
35 | # include <stdlib.h> | |
36 | #else | |
37 | # include "ansi_stdlib.h" | |
38 | #endif | |
39 | ||
ccc6cda3 JA |
40 | #include <stdio.h> |
41 | ||
42 | /* System-specific feature definitions and include files. */ | |
43 | #include "rldefs.h" | |
44 | #include "readline.h" | |
bb70624e | 45 | #include "rlprivate.h" |
0628567a | 46 | #include "xmalloc.h" |
ccc6cda3 | 47 | |
95732b49 JA |
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 | ||
ccc6cda3 JA |
53 | /* **************************************************************** */ |
54 | /* */ | |
95732b49 | 55 | /* Callback Readline Functions */ |
ccc6cda3 JA |
56 | /* */ |
57 | /* **************************************************************** */ | |
58 | ||
59 | /* Allow using readline in situations where a program may have multiple | |
60 | things to handle at once, and dispatches them via select(). Call | |
61 | rl_callback_handler_install() with the prompt and a function to call | |
62 | whenever a complete line of input is ready. The user must then | |
cce855bc JA |
63 | call rl_callback_read_char() every time some input is available, and |
64 | rl_callback_read_char() will call the user's function with the complete | |
65 | text read in at each end of line. The terminal is kept prepped and | |
66 | signals handled all the time, except during calls to the user's function. */ | |
ccc6cda3 | 67 | |
28ef6c31 | 68 | rl_vcpfunc_t *rl_linefunc; /* user callback function */ |
ccc6cda3 JA |
69 | static int in_handler; /* terminal_prepped and signals set? */ |
70 | ||
71 | /* Make sure the terminal is set up, initialize readline, and prompt. */ | |
72 | static void | |
73 | _rl_callback_newline () | |
74 | { | |
75 | rl_initialize (); | |
76 | ||
77 | if (in_handler == 0) | |
78 | { | |
79 | in_handler = 1; | |
80 | ||
95732b49 JA |
81 | if (rl_prep_term_function) |
82 | (*rl_prep_term_function) (_rl_meta_flag); | |
ccc6cda3 JA |
83 | |
84 | #if defined (HANDLE_SIGNALS) | |
85 | rl_set_signals (); | |
86 | #endif | |
87 | } | |
88 | ||
89 | readline_internal_setup (); | |
90 | } | |
91 | ||
92 | /* Install a readline handler, set up the terminal, and issue the prompt. */ | |
93 | void | |
94 | rl_callback_handler_install (prompt, linefunc) | |
28ef6c31 JA |
95 | const char *prompt; |
96 | rl_vcpfunc_t *linefunc; | |
ccc6cda3 | 97 | { |
28ef6c31 | 98 | rl_set_prompt (prompt); |
95732b49 | 99 | RL_SETSTATE (RL_STATE_CALLBACK); |
ccc6cda3 JA |
100 | rl_linefunc = linefunc; |
101 | _rl_callback_newline (); | |
102 | } | |
103 | ||
104 | /* Read one character, and dispatch to the handler if it ends the line. */ | |
105 | void | |
106 | rl_callback_read_char () | |
107 | { | |
108 | char *line; | |
95732b49 JA |
109 | int eof, jcode; |
110 | static procenv_t olevel; | |
ccc6cda3 JA |
111 | |
112 | if (rl_linefunc == NULL) | |
113 | { | |
114 | fprintf (stderr, "readline: readline_callback_read_char() called with no handler!\r\n"); | |
115 | abort (); | |
116 | } | |
117 | ||
95732b49 JA |
118 | memcpy ((void *)olevel, (void *)readline_top_level, sizeof (procenv_t)); |
119 | jcode = setjmp (readline_top_level); | |
120 | if (jcode) | |
121 | { | |
122 | (*rl_redisplay_function) (); | |
123 | _rl_want_redisplay = 0; | |
124 | memcpy ((void *)readline_top_level, (void *)olevel, sizeof (procenv_t)); | |
125 | return; | |
126 | } | |
127 | ||
0628567a | 128 | do |
95732b49 | 129 | { |
0628567a JA |
130 | if (RL_ISSTATE (RL_STATE_ISEARCH)) |
131 | { | |
132 | eof = _rl_isearch_callback (_rl_iscxt); | |
133 | if (eof == 0 && (RL_ISSTATE (RL_STATE_ISEARCH) == 0) && RL_ISSTATE (RL_STATE_INPUTPENDING)) | |
134 | rl_callback_read_char (); | |
95732b49 | 135 | |
0628567a JA |
136 | return; |
137 | } | |
138 | else if (RL_ISSTATE (RL_STATE_NSEARCH)) | |
95732b49 | 139 | { |
0628567a JA |
140 | eof = _rl_nsearch_callback (_rl_nscxt); |
141 | return; | |
95732b49 | 142 | } |
0628567a JA |
143 | else if (RL_ISSTATE (RL_STATE_NUMERICARG)) |
144 | { | |
145 | eof = _rl_arg_callback (_rl_argcxt); | |
146 | if (eof == 0 && (RL_ISSTATE (RL_STATE_NUMERICARG) == 0) && RL_ISSTATE (RL_STATE_INPUTPENDING)) | |
147 | rl_callback_read_char (); | |
148 | /* XXX - this should handle _rl_last_command_was_kill better */ | |
149 | else if (RL_ISSTATE (RL_STATE_NUMERICARG) == 0) | |
150 | _rl_internal_char_cleanup (); | |
151 | ||
152 | return; | |
153 | } | |
154 | else if (RL_ISSTATE (RL_STATE_MULTIKEY)) | |
95732b49 | 155 | { |
0628567a JA |
156 | eof = _rl_dispatch_callback (_rl_kscxt); /* For now */ |
157 | while ((eof == -1 || eof == -2) && RL_ISSTATE (RL_STATE_MULTIKEY) && _rl_kscxt && (_rl_kscxt->flags & KSEQ_DISPATCHED)) | |
158 | eof = _rl_dispatch_callback (_rl_kscxt); | |
159 | if (RL_ISSTATE (RL_STATE_MULTIKEY) == 0) | |
95732b49 | 160 | { |
0628567a JA |
161 | _rl_internal_char_cleanup (); |
162 | _rl_want_redisplay = 1; | |
95732b49 | 163 | } |
95732b49 | 164 | } |
0628567a JA |
165 | else if (_rl_callback_func) |
166 | { | |
167 | /* This allows functions that simply need to read an additional | |
168 | character (like quoted-insert) to register a function to be | |
169 | called when input is available. _rl_callback_data is simply a | |
170 | pointer to a struct that has the argument count originally | |
171 | passed to the registering function and space for any additional | |
172 | parameters. */ | |
173 | eof = (*_rl_callback_func) (_rl_callback_data); | |
174 | /* If the function `deregisters' itself, make sure the data is | |
175 | cleaned up. */ | |
176 | if (_rl_callback_func == 0) | |
177 | { | |
178 | if (_rl_callback_data) | |
179 | { | |
180 | _rl_callback_data_dispose (_rl_callback_data); | |
181 | _rl_callback_data = 0; | |
182 | } | |
183 | _rl_internal_char_cleanup (); | |
184 | } | |
185 | } | |
186 | else | |
187 | eof = readline_internal_char (); | |
95732b49 | 188 | |
0628567a JA |
189 | if (rl_done == 0 && _rl_want_redisplay) |
190 | { | |
191 | (*rl_redisplay_function) (); | |
192 | _rl_want_redisplay = 0; | |
193 | } | |
ccc6cda3 | 194 | |
28ef6c31 JA |
195 | if (rl_done) |
196 | { | |
197 | line = readline_internal_teardown (eof); | |
ccc6cda3 | 198 | |
95732b49 JA |
199 | if (rl_deprep_term_function) |
200 | (*rl_deprep_term_function) (); | |
ccc6cda3 | 201 | #if defined (HANDLE_SIGNALS) |
28ef6c31 | 202 | rl_clear_signals (); |
ccc6cda3 | 203 | #endif |
28ef6c31 JA |
204 | in_handler = 0; |
205 | (*rl_linefunc) (line); | |
206 | ||
207 | /* If the user did not clear out the line, do it for him. */ | |
208 | if (rl_line_buffer[0]) | |
209 | _rl_init_line_state (); | |
210 | ||
211 | /* Redisplay the prompt if readline_handler_{install,remove} | |
212 | not called. */ | |
213 | if (in_handler == 0 && rl_linefunc) | |
214 | _rl_callback_newline (); | |
215 | } | |
ccc6cda3 | 216 | } |
0628567a | 217 | while (rl_pending_input || _rl_pushed_input_available () || RL_ISSTATE (RL_STATE_MACROINPUT)); |
ccc6cda3 JA |
218 | } |
219 | ||
220 | /* Remove the handler, and make sure the terminal is in its normal state. */ | |
221 | void | |
222 | rl_callback_handler_remove () | |
223 | { | |
224 | rl_linefunc = NULL; | |
95732b49 | 225 | RL_UNSETSTATE (RL_STATE_CALLBACK); |
ccc6cda3 JA |
226 | if (in_handler) |
227 | { | |
228 | in_handler = 0; | |
95732b49 JA |
229 | if (rl_deprep_term_function) |
230 | (*rl_deprep_term_function) (); | |
ccc6cda3 JA |
231 | #if defined (HANDLE_SIGNALS) |
232 | rl_clear_signals (); | |
233 | #endif | |
234 | } | |
235 | } | |
236 | ||
95732b49 JA |
237 | _rl_callback_generic_arg * |
238 | _rl_callback_data_alloc (count) | |
239 | int count; | |
240 | { | |
241 | _rl_callback_generic_arg *arg; | |
242 | ||
243 | arg = (_rl_callback_generic_arg *)xmalloc (sizeof (_rl_callback_generic_arg)); | |
244 | arg->count = count; | |
245 | ||
246 | arg->i1 = arg->i2 = 0; | |
247 | ||
248 | return arg; | |
249 | } | |
250 | ||
251 | void _rl_callback_data_dispose (arg) | |
252 | _rl_callback_generic_arg *arg; | |
253 | { | |
254 | if (arg) | |
255 | free (arg); | |
256 | } | |
257 | ||
ccc6cda3 | 258 | #endif |