1: /* callback.c -- functions to use readline as an X `callback' mechanism. */
2:
3: /* Copyright (C) 1987-2009 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: /* **************************************************************** */
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
66: all the time, except during calls to the user's function. Signal
67: handlers are only installed when the application calls back into
68: readline, so readline doesn't `steal' signals from the application. */
69:
70: rl_vcpfunc_t *rl_linefunc; /* user callback function */
71: static int in_handler; /* terminal_prepped and signals set? */
72:
73: /* Make sure the terminal is set up, initialize readline, and prompt. */
74: static void
75: _rl_callback_newline ()
76: {
77: rl_initialize ();
78:
79: if (in_handler == 0)
80: {
81: in_handler = 1;
82:
83: if (rl_prep_term_function)
84: (*rl_prep_term_function) (_rl_meta_flag);
85: }
86:
87: readline_internal_setup ();
88: RL_CHECK_SIGNALS ();
89: }
90:
91: /* Install a readline handler, set up the terminal, and issue the prompt. */
92: void
93: rl_callback_handler_install (prompt, linefunc)
94: const char *prompt;
95: rl_vcpfunc_t *linefunc;
96: {
97: rl_set_prompt (prompt);
98: RL_SETSTATE (RL_STATE_CALLBACK);
99: rl_linefunc = linefunc;
100: _rl_callback_newline ();
101: }
102:
103: #if defined (HANDLE_SIGNALS)
104: #define CALLBACK_READ_RETURN() \
105: do { \
106: rl_clear_signals (); \
107: return; \
108: } while (0)
109: #else
110: #define CALLBACK_READ_RETURN() return
111: #endif
112:
113: /* Read one character, and dispatch to the handler if it ends the line. */
114: void
115: rl_callback_read_char ()
116: {
117: char *line;
118: int eof, jcode;
119: static procenv_t olevel;
120:
121: if (rl_linefunc == NULL)
122: {
123: _rl_errmsg ("readline_callback_read_char() called with no handler!");
124: abort ();
125: }
126:
127: memcpy ((void *)olevel, (void *)_rl_top_level, sizeof (procenv_t));
128: #if defined (HAVE_POSIX_SIGSETJMP)
129: jcode = sigsetjmp (_rl_top_level, 0);
130: #else
131: jcode = setjmp (_rl_top_level);
132: #endif
133: if (jcode)
134: {
135: (*rl_redisplay_function) ();
136: _rl_want_redisplay = 0;
137: memcpy ((void *)_rl_top_level, (void *)olevel, sizeof (procenv_t));
138: CALLBACK_READ_RETURN ();
139: }
140:
141: #if defined (HANDLE_SIGNALS)
142: /* Install signal handlers only when readline has control. */
143: rl_set_signals ();
144: #endif
145:
146: do
147: {
148: RL_CHECK_SIGNALS ();
149: if (RL_ISSTATE (RL_STATE_ISEARCH))
150: {
151: eof = _rl_isearch_callback (_rl_iscxt);
152: if (eof == 0 && (RL_ISSTATE (RL_STATE_ISEARCH) == 0) && RL_ISSTATE (RL_STATE_INPUTPENDING))
153: rl_callback_read_char ();
154:
155: CALLBACK_READ_RETURN ();
156: }
157: else if (RL_ISSTATE (RL_STATE_NSEARCH))
158: {
159: eof = _rl_nsearch_callback (_rl_nscxt);
160:
161: CALLBACK_READ_RETURN ();
162: }
163: #if defined (VI_MODE)
164: else if (RL_ISSTATE (RL_STATE_VIMOTION))
165: {
166: eof = _rl_vi_domove_callback (_rl_vimvcxt);
167: /* Should handle everything, including cleanup, numeric arguments,
168: and turning off RL_STATE_VIMOTION */
169: if (RL_ISSTATE (RL_STATE_NUMERICARG) == 0)
170: _rl_internal_char_cleanup ();
171:
172: CALLBACK_READ_RETURN ();
173: }
174: #endif
175: else if (RL_ISSTATE (RL_STATE_NUMERICARG))
176: {
177: eof = _rl_arg_callback (_rl_argcxt);
178: if (eof == 0 && (RL_ISSTATE (RL_STATE_NUMERICARG) == 0) && RL_ISSTATE (RL_STATE_INPUTPENDING))
179: rl_callback_read_char ();
180: /* XXX - this should handle _rl_last_command_was_kill better */
181: else if (RL_ISSTATE (RL_STATE_NUMERICARG) == 0)
182: _rl_internal_char_cleanup ();
183:
184: CALLBACK_READ_RETURN ();
185: }
186: else if (RL_ISSTATE (RL_STATE_MULTIKEY))
187: {
188: eof = _rl_dispatch_callback (_rl_kscxt); /* For now */
189: while ((eof == -1 || eof == -2) && RL_ISSTATE (RL_STATE_MULTIKEY) && _rl_kscxt && (_rl_kscxt->flags & KSEQ_DISPATCHED))
190: eof = _rl_dispatch_callback (_rl_kscxt);
191: if (RL_ISSTATE (RL_STATE_MULTIKEY) == 0)
192: {
193: _rl_internal_char_cleanup ();
194: _rl_want_redisplay = 1;
195: }
196: }
197: else if (_rl_callback_func)
198: {
199: /* This allows functions that simply need to read an additional
200: character (like quoted-insert) to register a function to be
201: called when input is available. _rl_callback_data is a
202: pointer to a struct that has the argument count originally
203: passed to the registering function and space for any additional
204: parameters. */
205: eof = (*_rl_callback_func) (_rl_callback_data);
206: /* If the function `deregisters' itself, make sure the data is
207: cleaned up. */
208: if (_rl_callback_func == 0)
209: {
210: if (_rl_callback_data)
211: {
212: _rl_callback_data_dispose (_rl_callback_data);
213: _rl_callback_data = 0;
214: }
215: _rl_internal_char_cleanup ();
216: }
217: }
218: else
219: eof = readline_internal_char ();
220:
221: RL_CHECK_SIGNALS ();
222: if (rl_done == 0 && _rl_want_redisplay)
223: {
224: (*rl_redisplay_function) ();
225: _rl_want_redisplay = 0;
226: }
227:
228: if (rl_done)
229: {
230: line = readline_internal_teardown (eof);
231:
232: if (rl_deprep_term_function)
233: (*rl_deprep_term_function) ();
234: #if defined (HANDLE_SIGNALS)
235: rl_clear_signals ();
236: #endif
237: in_handler = 0;
238: (*rl_linefunc) (line);
239:
240: /* If the user did not clear out the line, do it for him. */
241: if (rl_line_buffer[0])
242: _rl_init_line_state ();
243:
244: /* Redisplay the prompt if readline_handler_{install,remove}
245: not called. */
246: if (in_handler == 0 && rl_linefunc)
247: _rl_callback_newline ();
248: }
249: }
250: while (rl_pending_input || _rl_pushed_input_available () || RL_ISSTATE (RL_STATE_MACROINPUT));
251:
252: CALLBACK_READ_RETURN ();
253: }
254:
255: /* Remove the handler, and make sure the terminal is in its normal state. */
256: void
257: rl_callback_handler_remove ()
258: {
259: rl_linefunc = NULL;
260: RL_UNSETSTATE (RL_STATE_CALLBACK);
261: RL_CHECK_SIGNALS ();
262: if (in_handler)
263: {
264: in_handler = 0;
265: if (rl_deprep_term_function)
266: (*rl_deprep_term_function) ();
267: #if defined (HANDLE_SIGNALS)
268: rl_clear_signals ();
269: #endif
270: }
271: }
272:
273: _rl_callback_generic_arg *
274: _rl_callback_data_alloc (count)
275: int count;
276: {
277: _rl_callback_generic_arg *arg;
278:
279: arg = (_rl_callback_generic_arg *)xmalloc (sizeof (_rl_callback_generic_arg));
280: arg->count = count;
281:
282: arg->i1 = arg->i2 = 0;
283:
284: return arg;
285: }
286:
287: void _rl_callback_data_dispose (arg)
288: _rl_callback_generic_arg *arg;
289: {
290: xfree (arg);
291: }
292:
293: #endif
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>