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>