File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / readline / callback.c
Revision 1.1: download - view: text, annotated - select for diffs - revision graph
Wed Jul 30 08:16:45 2014 UTC (9 years, 11 months ago) by misho
CVS tags: MAIN, HEAD
Initial revision

    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>