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