2011-03-04 Michael Snyder <msnyder@vmware.com>
[deliverable/binutils-gdb.git] / readline / callback.c
index 34dbc724611a021efe23d56a2bbc0749d3fcde6d..697066e03c5b3ab778937017e5503967b0be158f 100644 (file)
@@ -1,13 +1,13 @@
 /* callback.c -- functions to use readline as an X `callback' mechanism. */
 
-/* Copyright (C) 1987, 1989, 1992 Free Software Foundation, Inc.
+/* Copyright (C) 1987-2005 Free Software Foundation, Inc.
 
    This file is part of the GNU Readline Library, a library for
    reading lines of text with interactive input and history editing.
 
    The GNU Readline Library is free software; you can redistribute it
    and/or modify it under the terms of the GNU General Public License
-   as published by the Free Software Foundation; either version 1, or
+   as published by the Free Software Foundation; either version 2, or
    (at your option) any later version.
 
    The GNU Readline Library is distributed in the hope that it will be
@@ -18,7 +18,7 @@
    The GNU General Public License is often shipped with GNU software, and
    is generally kept in a file called COPYING or LICENSE.  If you do not
    have a copy of the license, write to the Free Software Foundation,
-   675 Mass Ave, Cambridge, MA 02139, USA. */
+   59 Temple Place, Suite 330, Boston, MA 02111 USA. */
 #define READLINE_LIBRARY
 
 #if defined (HAVE_CONFIG_H)
 #if defined (READLINE_CALLBACKS)
 
 #include <sys/types.h>
+
+#ifdef HAVE_STDLIB_H
+#  include <stdlib.h>
+#else
+#  include "ansi_stdlib.h"
+#endif
+
 #include <stdio.h>
 
 /* System-specific feature definitions and include files. */
 #include "rldefs.h"
 #include "readline.h"
+#include "rlprivate.h"
+#include "xmalloc.h"
 
-extern void readline_internal_startup ();
-extern char *readline_internal_teardown ();
-extern int readline_internal_char ();
-extern void _rl_init_line_state ();
-
-extern int _rl_meta_flag;
-extern char *rl_prompt;
-extern int rl_visible_prompt_length;
+/* Private data for callback registration functions.  See comments in
+   rl_callback_read_char for more details. */
+_rl_callback_func_t *_rl_callback_func = 0;
+_rl_callback_generic_arg *_rl_callback_data = 0;
 
 /* **************************************************************** */
 /*                                                                 */
-/*                     Callback Readline Functions                 */
+/*                     Callback Readline Functions              */
 /*                                                                 */
 /* **************************************************************** */
 
@@ -60,7 +65,7 @@ extern int rl_visible_prompt_length;
    text read in at each end of line.  The terminal is kept prepped and
    signals handled all the time, except during calls to the user's function. */
 
-VFunction *rl_linefunc;                /* user callback function */
+rl_vcpfunc_t *rl_linefunc;             /* user callback function */
 static int in_handler;         /* terminal_prepped and signals set? */
 
 /* Make sure the terminal is set up, initialize readline, and prompt. */
@@ -73,7 +78,8 @@ _rl_callback_newline ()
     {
       in_handler = 1;
 
-      (*rl_prep_term_function) (_rl_meta_flag);
+      if (rl_prep_term_function)
+       (*rl_prep_term_function) (_rl_meta_flag);
 
 #if defined (HANDLE_SIGNALS)
       rl_set_signals ();
@@ -86,11 +92,11 @@ _rl_callback_newline ()
 /* Install a readline handler, set up the terminal, and issue the prompt. */
 void
 rl_callback_handler_install (prompt, linefunc)
-     char *prompt;
-     VFunction *linefunc;
+     const char *prompt;
+     rl_vcpfunc_t *linefunc;
 {
-  rl_prompt = prompt;
-  rl_visible_prompt_length = rl_prompt ? rl_expand_prompt (rl_prompt) : 0;
+  rl_set_prompt (prompt);
+  RL_SETSTATE (RL_STATE_CALLBACK);
   rl_linefunc = linefunc;
   _rl_callback_newline ();
 }
@@ -100,7 +106,8 @@ void
 rl_callback_read_char ()
 {
   char *line;
-  int eof;
+  int eof, jcode;
+  static procenv_t olevel;
 
   if (rl_linefunc == NULL)
     {
@@ -108,26 +115,108 @@ rl_callback_read_char ()
       abort ();
     }
 
-  eof = readline_internal_char ();
+  memcpy ((void *)olevel, (void *)readline_top_level, sizeof (procenv_t));
+  jcode = setjmp (readline_top_level);
+  if (jcode)
+    {
+      (*rl_redisplay_function) ();
+      _rl_want_redisplay = 0;
+      memcpy ((void *)readline_top_level, (void *)olevel, sizeof (procenv_t));
+      return;
+    }
+
+  if  (RL_ISSTATE (RL_STATE_ISEARCH))
+    {
+      eof = _rl_isearch_callback (_rl_iscxt);
+      if (eof == 0 && (RL_ISSTATE (RL_STATE_ISEARCH) == 0) && RL_ISSTATE (RL_STATE_INPUTPENDING))
+       rl_callback_read_char ();
 
-  if (rl_done)
+      return;
+    }
+  else if  (RL_ISSTATE (RL_STATE_NSEARCH))
     {
-      line = readline_internal_teardown (eof);
+      eof = _rl_nsearch_callback (_rl_nscxt);
+      return;
+    }
+  else if (RL_ISSTATE (RL_STATE_NUMERICARG))
+    {
+      eof = _rl_arg_callback (_rl_argcxt);
+      if (eof == 0 && (RL_ISSTATE (RL_STATE_NUMERICARG) == 0) && RL_ISSTATE (RL_STATE_INPUTPENDING))
+       rl_callback_read_char ();
+      /* XXX - this should handle _rl_last_command_was_kill better */
+      else if (RL_ISSTATE (RL_STATE_NUMERICARG) == 0)
+       _rl_internal_char_cleanup ();
+
+      return;
+    }
+  else if (RL_ISSTATE (RL_STATE_MULTIKEY))
+    {
+      eof = _rl_dispatch_callback (_rl_kscxt); /* For now */
+      while ((eof == -1 || eof == -2) && RL_ISSTATE (RL_STATE_MULTIKEY) && _rl_kscxt && (_rl_kscxt->flags & KSEQ_DISPATCHED))
+       eof = _rl_dispatch_callback (_rl_kscxt);
+      if (RL_ISSTATE (RL_STATE_MULTIKEY) == 0)
+       {
+         _rl_internal_char_cleanup ();
+         _rl_want_redisplay = 1;
+       }
+    }
+  else if (_rl_callback_func)
+    {
+      /* This allows functions that simply need to read an additional character
+        (like quoted-insert) to register a function to be called when input is
+        available.  _rl_callback_data is simply a pointer to a struct that has
+        the argument count originally passed to the registering function and
+        space for any additional parameters.  */
+      eof = (*_rl_callback_func) (_rl_callback_data);
+      /* If the function `deregisters' itself, make sure the data is cleaned
+        up. */
+      if (_rl_callback_func == 0)
+       {
+         if (_rl_callback_data)        
+           {
+             _rl_callback_data_dispose (_rl_callback_data);
+             _rl_callback_data = 0;
+           }
+         _rl_internal_char_cleanup ();
+       }
+    }
+  else
+    eof = readline_internal_char ();
 
-      (*rl_deprep_term_function) ();
+  if (rl_done == 0 && _rl_want_redisplay)
+    {
+      (*rl_redisplay_function) ();
+      _rl_want_redisplay = 0;
+    }
+
+  /* We loop in case some function has pushed input back with rl_execute_next. */
+  for (;;)
+    {
+      if (rl_done)
+       {
+         line = readline_internal_teardown (eof);
+
+         if (rl_deprep_term_function)
+           (*rl_deprep_term_function) ();
 #if defined (HANDLE_SIGNALS)
-      rl_clear_signals ();
+         rl_clear_signals ();
 #endif
-      in_handler = 0;
-      (*rl_linefunc) (line);
+         in_handler = 0;
+         (*rl_linefunc) (line);
 
-    /* If the user did not clear out the line, do it for him. */
-    if (rl_line_buffer[0])
-      _rl_init_line_state ();
+         /* If the user did not clear out the line, do it for him. */
+         if (rl_line_buffer[0])
+           _rl_init_line_state ();
 
-    /* Redisplay the prompt if readline_handler_{install,remove} not called. */
-      if (in_handler == 0 && rl_linefunc)
-       _rl_callback_newline ();
+         /* Redisplay the prompt if readline_handler_{install,remove}
+            not called. */
+         if (in_handler == 0 && rl_linefunc)
+           _rl_callback_newline ();
+       }
+      if (rl_pending_input || _rl_pushed_input_available () || RL_ISSTATE (RL_STATE_MACROINPUT))
+       eof = readline_internal_char ();
+      else
+       break;
     }
 }
 
@@ -136,14 +225,37 @@ void
 rl_callback_handler_remove ()
 {
   rl_linefunc = NULL;
+  RL_UNSETSTATE (RL_STATE_CALLBACK);
   if (in_handler)
     {
       in_handler = 0;
-      (*rl_deprep_term_function) ();
+      if (rl_deprep_term_function)
+       (*rl_deprep_term_function) ();
 #if defined (HANDLE_SIGNALS)
       rl_clear_signals ();
 #endif
     }
 }
 
+_rl_callback_generic_arg *
+_rl_callback_data_alloc (count)
+     int count;
+{
+  _rl_callback_generic_arg *arg;
+
+  arg = (_rl_callback_generic_arg *)xmalloc (sizeof (_rl_callback_generic_arg));
+  arg->count = count;
+
+  arg->i1 = arg->i2 = 0;
+
+  return arg;
+}
+
+void _rl_callback_data_dispose (arg)
+     _rl_callback_generic_arg *arg;
+{
+  if (arg)
+    free (arg);
+}
+
 #endif
This page took 0.027828 seconds and 4 git commands to generate.