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

1.1       misho       1: /* callback.c -- functions to use readline as an X `callback' mechanism. */
                      2: 
1.1.1.2 ! misho       3: /* Copyright (C) 1987-2017 Free Software Foundation, Inc.
1.1       misho       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: 
1.1.1.2 ! misho      53: /* Applications can set this to non-zero to have readline's signal handlers
        !            54:    installed during the entire duration of reading a complete line, as in
        !            55:    readline-6.2.  This should be used with care, because it can result in
        !            56:    readline receiving signals and not handling them until it's called again
        !            57:    via rl_callback_read_char, thereby stealing them from the application.
        !            58:    By default, signal handlers are only active while readline is active. */   
        !            59: int rl_persistent_signal_handlers = 0;
        !            60: 
1.1       misho      61: /* **************************************************************** */
                     62: /*                                                                 */
1.1.1.2 ! misho      63: /*                     Callback Readline Functions                 */
1.1       misho      64: /*                                                                 */
                     65: /* **************************************************************** */
                     66: 
                     67: /* Allow using readline in situations where a program may have multiple
                     68:    things to handle at once, and dispatches them via select().  Call
                     69:    rl_callback_handler_install() with the prompt and a function to call
                     70:    whenever a complete line of input is ready.  The user must then
                     71:    call rl_callback_read_char() every time some input is available, and 
                     72:    rl_callback_read_char() will call the user's function with the complete
                     73:    text read in at each end of line.  The terminal is kept prepped
                     74:    all the time, except during calls to the user's function.  Signal
                     75:    handlers are only installed when the application calls back into
                     76:    readline, so readline doesn't `steal' signals from the application.  */
                     77: 
                     78: rl_vcpfunc_t *rl_linefunc;             /* user callback function */
                     79: static int in_handler;         /* terminal_prepped and signals set? */
                     80: 
                     81: /* Make sure the terminal is set up, initialize readline, and prompt. */
                     82: static void
1.1.1.2 ! misho      83: _rl_callback_newline (void)
1.1       misho      84: {
                     85:   rl_initialize ();
                     86: 
                     87:   if (in_handler == 0)
                     88:     {
                     89:       in_handler = 1;
                     90: 
                     91:       if (rl_prep_term_function)
                     92:        (*rl_prep_term_function) (_rl_meta_flag);
1.1.1.2 ! misho      93: 
        !            94: #if defined (HANDLE_SIGNALS)
        !            95:       if (rl_persistent_signal_handlers)
        !            96:        rl_set_signals ();
        !            97: #endif
1.1       misho      98:     }
                     99: 
                    100:   readline_internal_setup ();
                    101:   RL_CHECK_SIGNALS ();
                    102: }
                    103: 
                    104: /* Install a readline handler, set up the terminal, and issue the prompt. */
                    105: void
1.1.1.2 ! misho     106: rl_callback_handler_install (const char *prompt, rl_vcpfunc_t *linefunc)
1.1       misho     107: {
                    108:   rl_set_prompt (prompt);
                    109:   RL_SETSTATE (RL_STATE_CALLBACK);
                    110:   rl_linefunc = linefunc;
                    111:   _rl_callback_newline ();
                    112: }
                    113: 
                    114: #if defined (HANDLE_SIGNALS)
                    115: #define CALLBACK_READ_RETURN() \
                    116:   do { \
1.1.1.2 ! misho     117:     if (rl_persistent_signal_handlers == 0) \
        !           118:       rl_clear_signals (); \
1.1       misho     119:     return; \
                    120:   } while (0)
                    121: #else
                    122: #define CALLBACK_READ_RETURN() return
                    123: #endif
                    124: 
                    125: /* Read one character, and dispatch to the handler if it ends the line. */
                    126: void
1.1.1.2 ! misho     127: rl_callback_read_char (void)
1.1       misho     128: {
                    129:   char *line;
                    130:   int eof, jcode;
                    131:   static procenv_t olevel;
                    132: 
                    133:   if (rl_linefunc == NULL)
                    134:     {
                    135:       _rl_errmsg ("readline_callback_read_char() called with no handler!");
                    136:       abort ();
                    137:     }
                    138: 
                    139:   memcpy ((void *)olevel, (void *)_rl_top_level, sizeof (procenv_t));
                    140: #if defined (HAVE_POSIX_SIGSETJMP)
                    141:   jcode = sigsetjmp (_rl_top_level, 0);
                    142: #else
                    143:   jcode = setjmp (_rl_top_level);
                    144: #endif
                    145:   if (jcode)
                    146:     {
                    147:       (*rl_redisplay_function) ();
                    148:       _rl_want_redisplay = 0;
                    149:       memcpy ((void *)_rl_top_level, (void *)olevel, sizeof (procenv_t));
                    150:       CALLBACK_READ_RETURN ();
                    151:     }
                    152: 
                    153: #if defined (HANDLE_SIGNALS)
                    154:   /* Install signal handlers only when readline has control. */
1.1.1.2 ! misho     155:   if (rl_persistent_signal_handlers == 0)
        !           156:     rl_set_signals ();
1.1       misho     157: #endif
                    158: 
                    159:   do
                    160:     {
                    161:       RL_CHECK_SIGNALS ();
                    162:       if  (RL_ISSTATE (RL_STATE_ISEARCH))
                    163:        {
                    164:          eof = _rl_isearch_callback (_rl_iscxt);
                    165:          if (eof == 0 && (RL_ISSTATE (RL_STATE_ISEARCH) == 0) && RL_ISSTATE (RL_STATE_INPUTPENDING))
                    166:            rl_callback_read_char ();
                    167: 
                    168:          CALLBACK_READ_RETURN ();
                    169:        }
                    170:       else if  (RL_ISSTATE (RL_STATE_NSEARCH))
                    171:        {
                    172:          eof = _rl_nsearch_callback (_rl_nscxt);
                    173: 
                    174:          CALLBACK_READ_RETURN ();
                    175:        }
                    176: #if defined (VI_MODE)
1.1.1.2 ! misho     177:       /* States that can occur while in state VIMOTION have to be checked
        !           178:         before RL_STATE_VIMOTION */
        !           179:       else if (RL_ISSTATE (RL_STATE_CHARSEARCH))
        !           180:        {
        !           181:          int k;
        !           182: 
        !           183:          k = _rl_callback_data->i2;
        !           184: 
        !           185:          eof = (*_rl_callback_func) (_rl_callback_data);
        !           186:          /* If the function `deregisters' itself, make sure the data is
        !           187:             cleaned up. */
        !           188:          if (_rl_callback_func == 0)   /* XXX - just sanity check */
        !           189:            {
        !           190:              if (_rl_callback_data)
        !           191:                {
        !           192:                  _rl_callback_data_dispose (_rl_callback_data);
        !           193:                  _rl_callback_data = 0;
        !           194:                }
        !           195:            }
        !           196: 
        !           197:          /* Messy case where vi motion command can be char search */
        !           198:          if (RL_ISSTATE (RL_STATE_VIMOTION))
        !           199:            {
        !           200:              _rl_vi_domove_motion_cleanup (k, _rl_vimvcxt);
        !           201:              _rl_internal_char_cleanup ();
        !           202:              CALLBACK_READ_RETURN ();        
        !           203:            }
        !           204: 
        !           205:          _rl_internal_char_cleanup ();
        !           206:        }
1.1       misho     207:       else if (RL_ISSTATE (RL_STATE_VIMOTION))
                    208:        {
                    209:          eof = _rl_vi_domove_callback (_rl_vimvcxt);
                    210:          /* Should handle everything, including cleanup, numeric arguments,
                    211:             and turning off RL_STATE_VIMOTION */
                    212:          if (RL_ISSTATE (RL_STATE_NUMERICARG) == 0)
                    213:            _rl_internal_char_cleanup ();
                    214: 
                    215:          CALLBACK_READ_RETURN ();
                    216:        }
                    217: #endif
                    218:       else if (RL_ISSTATE (RL_STATE_NUMERICARG))
                    219:        {
                    220:          eof = _rl_arg_callback (_rl_argcxt);
                    221:          if (eof == 0 && (RL_ISSTATE (RL_STATE_NUMERICARG) == 0) && RL_ISSTATE (RL_STATE_INPUTPENDING))
                    222:            rl_callback_read_char ();
                    223:          /* XXX - this should handle _rl_last_command_was_kill better */
                    224:          else if (RL_ISSTATE (RL_STATE_NUMERICARG) == 0)
                    225:            _rl_internal_char_cleanup ();
                    226: 
                    227:          CALLBACK_READ_RETURN ();
                    228:        }
                    229:       else if (RL_ISSTATE (RL_STATE_MULTIKEY))
                    230:        {
                    231:          eof = _rl_dispatch_callback (_rl_kscxt);      /* For now */
                    232:          while ((eof == -1 || eof == -2) && RL_ISSTATE (RL_STATE_MULTIKEY) && _rl_kscxt && (_rl_kscxt->flags & KSEQ_DISPATCHED))
                    233:            eof = _rl_dispatch_callback (_rl_kscxt);
                    234:          if (RL_ISSTATE (RL_STATE_MULTIKEY) == 0)
                    235:            {
                    236:              _rl_internal_char_cleanup ();
                    237:              _rl_want_redisplay = 1;
                    238:            }
                    239:        }
                    240:       else if (_rl_callback_func)
                    241:        {
                    242:          /* This allows functions that simply need to read an additional
                    243:             character (like quoted-insert) to register a function to be
                    244:             called when input is available.  _rl_callback_data is a
                    245:             pointer to a struct that has the argument count originally
                    246:             passed to the registering function and space for any additional
                    247:             parameters.  */
                    248:          eof = (*_rl_callback_func) (_rl_callback_data);
                    249:          /* If the function `deregisters' itself, make sure the data is
                    250:             cleaned up. */
                    251:          if (_rl_callback_func == 0)
                    252:            {
                    253:              if (_rl_callback_data)    
                    254:                {
                    255:                  _rl_callback_data_dispose (_rl_callback_data);
                    256:                  _rl_callback_data = 0;
                    257:                }
                    258:              _rl_internal_char_cleanup ();
                    259:            }
                    260:        }
                    261:       else
                    262:        eof = readline_internal_char ();
                    263: 
                    264:       RL_CHECK_SIGNALS ();
                    265:       if (rl_done == 0 && _rl_want_redisplay)
                    266:        {
                    267:          (*rl_redisplay_function) ();
                    268:          _rl_want_redisplay = 0;
                    269:        }
                    270: 
                    271:       if (rl_done)
                    272:        {
                    273:          line = readline_internal_teardown (eof);
                    274: 
                    275:          if (rl_deprep_term_function)
                    276:            (*rl_deprep_term_function) ();
                    277: #if defined (HANDLE_SIGNALS)
                    278:          rl_clear_signals ();
                    279: #endif
                    280:          in_handler = 0;
                    281:          (*rl_linefunc) (line);
                    282: 
                    283:          /* If the user did not clear out the line, do it for him. */
                    284:          if (rl_line_buffer[0])
                    285:            _rl_init_line_state ();
                    286: 
                    287:          /* Redisplay the prompt if readline_handler_{install,remove}
                    288:             not called. */
                    289:          if (in_handler == 0 && rl_linefunc)
                    290:            _rl_callback_newline ();
                    291:        }
                    292:     }
                    293:   while (rl_pending_input || _rl_pushed_input_available () || RL_ISSTATE (RL_STATE_MACROINPUT));
                    294: 
                    295:   CALLBACK_READ_RETURN ();
                    296: }
                    297: 
                    298: /* Remove the handler, and make sure the terminal is in its normal state. */
                    299: void
1.1.1.2 ! misho     300: rl_callback_handler_remove (void)
1.1       misho     301: {
                    302:   rl_linefunc = NULL;
                    303:   RL_UNSETSTATE (RL_STATE_CALLBACK);
                    304:   RL_CHECK_SIGNALS ();
                    305:   if (in_handler)
                    306:     {
                    307:       in_handler = 0;
                    308:       if (rl_deprep_term_function)
                    309:        (*rl_deprep_term_function) ();
                    310: #if defined (HANDLE_SIGNALS)
                    311:       rl_clear_signals ();
                    312: #endif
                    313:     }
                    314: }
                    315: 
                    316: _rl_callback_generic_arg *
1.1.1.2 ! misho     317: _rl_callback_data_alloc (int count)
1.1       misho     318: {
                    319:   _rl_callback_generic_arg *arg;
                    320: 
                    321:   arg = (_rl_callback_generic_arg *)xmalloc (sizeof (_rl_callback_generic_arg));
                    322:   arg->count = count;
                    323: 
                    324:   arg->i1 = arg->i2 = 0;
                    325: 
                    326:   return arg;
                    327: }
                    328: 
1.1.1.2 ! misho     329: void
        !           330: _rl_callback_data_dispose (_rl_callback_generic_arg *arg)
1.1       misho     331: {
                    332:   xfree (arg);
                    333: }
                    334: 
1.1.1.2 ! misho     335: /* Make sure that this agrees with cases in rl_callback_read_char */
        !           336: void
        !           337: rl_callback_sigcleanup (void)
        !           338: {
        !           339:   if (RL_ISSTATE (RL_STATE_CALLBACK) == 0)
        !           340:     return;
        !           341: 
        !           342:   if (RL_ISSTATE (RL_STATE_ISEARCH))
        !           343:     _rl_isearch_cleanup (_rl_iscxt, 0);
        !           344:   else if (RL_ISSTATE (RL_STATE_NSEARCH))
        !           345:     _rl_nsearch_cleanup (_rl_nscxt, 0);
        !           346:   else if (RL_ISSTATE (RL_STATE_VIMOTION))
        !           347:     RL_UNSETSTATE (RL_STATE_VIMOTION);
        !           348:   else if (RL_ISSTATE (RL_STATE_NUMERICARG))
        !           349:     {
        !           350:       _rl_argcxt = 0;
        !           351:       RL_UNSETSTATE (RL_STATE_NUMERICARG);
        !           352:     }
        !           353:   else if (RL_ISSTATE (RL_STATE_MULTIKEY))
        !           354:     RL_UNSETSTATE (RL_STATE_MULTIKEY);
        !           355:   if (RL_ISSTATE (RL_STATE_CHARSEARCH))
        !           356:     RL_UNSETSTATE (RL_STATE_CHARSEARCH);
        !           357: 
        !           358:   _rl_callback_func = 0;
        !           359: }
1.1       misho     360: #endif

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>