1 | /* callback.c -- functions to use readline as an X `callback' mechanism. */ |
2 | |
3 | /* Copyright (C) 1987-2005 Free Software Foundation, Inc. |
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 |
10 | as published by the Free Software Foundation; either version 2, or |
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, |
21 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ |
22 | #define READLINE_LIBRARY |
23 | |
24 | #if defined (HAVE_CONFIG_H) |
25 | # include "config_readline.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 | /* **************************************************************** */ |
54 | /* */ |
55 | /* Callback Readline Functions */ |
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 |
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. */ |
67 | |
68 | rl_vcpfunc_t *rl_linefunc; /* user callback function */ |
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 | |
81 | if (rl_prep_term_function) |
82 | (*rl_prep_term_function) (_rl_meta_flag); |
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) |
95 | const char *prompt; |
96 | rl_vcpfunc_t *linefunc; |
97 | { |
98 | rl_set_prompt (prompt); |
99 | RL_SETSTATE (RL_STATE_CALLBACK); |
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; |
109 | int eof, jcode; |
110 | static procenv_t olevel; |
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 | |
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 | |
128 | do |
129 | { |
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 (); |
135 | |
136 | return; |
137 | } |
138 | else if (RL_ISSTATE (RL_STATE_NSEARCH)) |
139 | { |
140 | eof = _rl_nsearch_callback (_rl_nscxt); |
141 | return; |
142 | } |
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)) |
155 | { |
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) |
160 | { |
161 | _rl_internal_char_cleanup (); |
162 | _rl_want_redisplay = 1; |
163 | } |
164 | } |
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 (); |
188 | |
189 | if (rl_done == 0 && _rl_want_redisplay) |
190 | { |
191 | (*rl_redisplay_function) (); |
192 | _rl_want_redisplay = 0; |
193 | } |
194 | |
195 | if (rl_done) |
196 | { |
197 | line = readline_internal_teardown (eof); |
198 | |
199 | if (rl_deprep_term_function) |
200 | (*rl_deprep_term_function) (); |
201 | #if defined (HANDLE_SIGNALS) |
202 | rl_clear_signals (); |
203 | #endif |
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 | } |
216 | } |
217 | while (rl_pending_input || _rl_pushed_input_available () || RL_ISSTATE (RL_STATE_MACROINPUT)); |
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; |
225 | RL_UNSETSTATE (RL_STATE_CALLBACK); |
226 | if (in_handler) |
227 | { |
228 | in_handler = 0; |
229 | if (rl_deprep_term_function) |
230 | (*rl_deprep_term_function) (); |
231 | #if defined (HANDLE_SIGNALS) |
232 | rl_clear_signals (); |
233 | #endif |
234 | } |
235 | } |
236 | |
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 | |
258 | #endif |
259 | |