Annotation of embedaddon/readline/callback.c, revision 1.1

1.1     ! misho       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>