xref: /openbsd-src/gnu/lib/libreadline/callback.c (revision 9704b281e65e1189747652d0ba55eee892cff5f7)
11acd27e7Smillert /* callback.c -- functions to use readline as an X `callback' mechanism. */
21acd27e7Smillert 
31acd27e7Smillert /* Copyright (C) 1987, 1989, 1992 Free Software Foundation, Inc.
41acd27e7Smillert 
51acd27e7Smillert    This file is part of the GNU Readline Library, a library for
61acd27e7Smillert    reading lines of text with interactive input and history editing.
71acd27e7Smillert 
81acd27e7Smillert    The GNU Readline Library is free software; you can redistribute it
91acd27e7Smillert    and/or modify it under the terms of the GNU General Public License
101acd27e7Smillert    as published by the Free Software Foundation; either version 2, or
111acd27e7Smillert    (at your option) any later version.
121acd27e7Smillert 
131acd27e7Smillert    The GNU Readline Library is distributed in the hope that it will be
141acd27e7Smillert    useful, but WITHOUT ANY WARRANTY; without even the implied warranty
151acd27e7Smillert    of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
161acd27e7Smillert    GNU General Public License for more details.
171acd27e7Smillert 
181acd27e7Smillert    The GNU General Public License is often shipped with GNU software, and
191acd27e7Smillert    is generally kept in a file called COPYING or LICENSE.  If you do not
201acd27e7Smillert    have a copy of the license, write to the Free Software Foundation,
211acd27e7Smillert    59 Temple Place, Suite 330, Boston, MA 02111 USA. */
221acd27e7Smillert #define READLINE_LIBRARY
231acd27e7Smillert 
241acd27e7Smillert #if defined (HAVE_CONFIG_H)
251acd27e7Smillert #  include <config.h>
261acd27e7Smillert #endif
271acd27e7Smillert 
281acd27e7Smillert #include "rlconf.h"
291acd27e7Smillert 
301acd27e7Smillert #if defined (READLINE_CALLBACKS)
311acd27e7Smillert 
321acd27e7Smillert #include <sys/types.h>
3315b117eaSkettenis 
3415b117eaSkettenis #ifdef HAVE_STDLIB_H
3515b117eaSkettenis #  include <stdlib.h>
3615b117eaSkettenis #else
3715b117eaSkettenis #  include "ansi_stdlib.h"
3815b117eaSkettenis #endif
3915b117eaSkettenis 
401acd27e7Smillert #include <stdio.h>
411acd27e7Smillert 
421acd27e7Smillert /* System-specific feature definitions and include files. */
431acd27e7Smillert #include "rldefs.h"
441acd27e7Smillert #include "readline.h"
451acd27e7Smillert #include "rlprivate.h"
461acd27e7Smillert 
471acd27e7Smillert /* **************************************************************** */
481acd27e7Smillert /*								    */
491acd27e7Smillert /*			Callback Readline Functions                 */
501acd27e7Smillert /*								    */
511acd27e7Smillert /* **************************************************************** */
521acd27e7Smillert 
531acd27e7Smillert /* Allow using readline in situations where a program may have multiple
541acd27e7Smillert    things to handle at once, and dispatches them via select().  Call
551acd27e7Smillert    rl_callback_handler_install() with the prompt and a function to call
561acd27e7Smillert    whenever a complete line of input is ready.  The user must then
571acd27e7Smillert    call rl_callback_read_char() every time some input is available, and
581acd27e7Smillert    rl_callback_read_char() will call the user's function with the complete
591acd27e7Smillert    text read in at each end of line.  The terminal is kept prepped and
601acd27e7Smillert    signals handled all the time, except during calls to the user's function. */
611acd27e7Smillert 
6215b117eaSkettenis rl_vcpfunc_t *rl_linefunc;		/* user callback function */
631acd27e7Smillert static int in_handler;		/* terminal_prepped and signals set? */
641acd27e7Smillert 
651acd27e7Smillert /* Make sure the terminal is set up, initialize readline, and prompt. */
661acd27e7Smillert static void
_rl_callback_newline()671acd27e7Smillert _rl_callback_newline ()
681acd27e7Smillert {
691acd27e7Smillert   rl_initialize ();
701acd27e7Smillert 
711acd27e7Smillert   if (in_handler == 0)
721acd27e7Smillert     {
731acd27e7Smillert       in_handler = 1;
741acd27e7Smillert 
751acd27e7Smillert       (*rl_prep_term_function) (_rl_meta_flag);
761acd27e7Smillert 
771acd27e7Smillert #if defined (HANDLE_SIGNALS)
781acd27e7Smillert       rl_set_signals ();
791acd27e7Smillert #endif
801acd27e7Smillert     }
811acd27e7Smillert 
821acd27e7Smillert   readline_internal_setup ();
831acd27e7Smillert }
841acd27e7Smillert 
851acd27e7Smillert /* Install a readline handler, set up the terminal, and issue the prompt. */
861acd27e7Smillert void
rl_callback_handler_install(prompt,linefunc)871acd27e7Smillert rl_callback_handler_install (prompt, linefunc)
8815b117eaSkettenis      const char *prompt;
8915b117eaSkettenis      rl_vcpfunc_t *linefunc;
901acd27e7Smillert {
9115b117eaSkettenis   rl_set_prompt (prompt);
921acd27e7Smillert   rl_linefunc = linefunc;
931acd27e7Smillert   _rl_callback_newline ();
941acd27e7Smillert }
951acd27e7Smillert 
961acd27e7Smillert /* Read one character, and dispatch to the handler if it ends the line. */
971acd27e7Smillert void
rl_callback_read_char()981acd27e7Smillert rl_callback_read_char ()
991acd27e7Smillert {
1001acd27e7Smillert   char *line;
1011acd27e7Smillert   int eof;
1021acd27e7Smillert 
1031acd27e7Smillert   if (rl_linefunc == NULL)
1041acd27e7Smillert     {
1051acd27e7Smillert       fprintf (stderr, "readline: readline_callback_read_char() called with no handler!\r\n");
1061acd27e7Smillert       abort ();
1071acd27e7Smillert     }
1081acd27e7Smillert 
1091acd27e7Smillert   eof = readline_internal_char ();
1101acd27e7Smillert 
11115b117eaSkettenis   /* We loop in case some function has pushed input back with rl_execute_next. */
11215b117eaSkettenis   for (;;)
11315b117eaSkettenis     {
1141acd27e7Smillert       if (rl_done)
1151acd27e7Smillert 	{
1161acd27e7Smillert 	  line = readline_internal_teardown (eof);
1171acd27e7Smillert 
1181acd27e7Smillert 	  (*rl_deprep_term_function) ();
1191acd27e7Smillert #if defined (HANDLE_SIGNALS)
1201acd27e7Smillert 	  rl_clear_signals ();
1211acd27e7Smillert #endif
1221acd27e7Smillert 	  in_handler = 0;
1231acd27e7Smillert 	  (*rl_linefunc) (line);
1241acd27e7Smillert 
1251acd27e7Smillert 	  /* If the user did not clear out the line, do it for him. */
1261acd27e7Smillert 	  if (rl_line_buffer[0])
1271acd27e7Smillert 	    _rl_init_line_state ();
1281acd27e7Smillert 
12915b117eaSkettenis 	  /* Redisplay the prompt if readline_handler_{install,remove}
13015b117eaSkettenis 	     not called. */
1311acd27e7Smillert 	  if (in_handler == 0 && rl_linefunc)
1321acd27e7Smillert 	    _rl_callback_newline ();
1331acd27e7Smillert 	}
134*27b28cd4Snicm       if (rl_pending_input || _rl_pushed_input_available ())
13515b117eaSkettenis 	eof = readline_internal_char ();
13615b117eaSkettenis       else
13715b117eaSkettenis         break;
13815b117eaSkettenis     }
1391acd27e7Smillert }
1401acd27e7Smillert 
1411acd27e7Smillert /* Remove the handler, and make sure the terminal is in its normal state. */
1421acd27e7Smillert void
rl_callback_handler_remove()1431acd27e7Smillert rl_callback_handler_remove ()
1441acd27e7Smillert {
1451acd27e7Smillert   rl_linefunc = NULL;
1461acd27e7Smillert   if (in_handler)
1471acd27e7Smillert     {
1481acd27e7Smillert       in_handler = 0;
1491acd27e7Smillert       (*rl_deprep_term_function) ();
1501acd27e7Smillert #if defined (HANDLE_SIGNALS)
1511acd27e7Smillert       rl_clear_signals ();
1521acd27e7Smillert #endif
1531acd27e7Smillert     }
1541acd27e7Smillert }
1551acd27e7Smillert 
1561acd27e7Smillert #endif
157