Annotation of embedaddon/readline/macro.c, revision 1.1
1.1 ! misho 1: /* macro.c -- keyboard macros for readline. */
! 2:
! 3: /* Copyright (C) 1994-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 <sys/types.h>
! 29:
! 30: #if defined (HAVE_UNISTD_H)
! 31: # include <unistd.h> /* for _POSIX_VERSION */
! 32: #endif /* HAVE_UNISTD_H */
! 33:
! 34: #if defined (HAVE_STDLIB_H)
! 35: # include <stdlib.h>
! 36: #else
! 37: # include "ansi_stdlib.h"
! 38: #endif /* HAVE_STDLIB_H */
! 39:
! 40: #include <stdio.h>
! 41:
! 42: /* System-specific feature definitions and include files. */
! 43: #include "rldefs.h"
! 44:
! 45: /* Some standard library routines. */
! 46: #include "readline.h"
! 47: #include "history.h"
! 48:
! 49: #include "rlprivate.h"
! 50: #include "xmalloc.h"
! 51:
! 52: /* **************************************************************** */
! 53: /* */
! 54: /* Hacking Keyboard Macros */
! 55: /* */
! 56: /* **************************************************************** */
! 57:
! 58: /* The currently executing macro string. If this is non-zero,
! 59: then it is a malloc ()'ed string where input is coming from. */
! 60: char *rl_executing_macro = (char *)NULL;
! 61:
! 62: /* The offset in the above string to the next character to be read. */
! 63: static int executing_macro_index;
! 64:
! 65: /* The current macro string being built. Characters get stuffed
! 66: in here by add_macro_char (). */
! 67: static char *current_macro = (char *)NULL;
! 68:
! 69: /* The size of the buffer allocated to current_macro. */
! 70: static int current_macro_size;
! 71:
! 72: /* The index at which characters are being added to current_macro. */
! 73: static int current_macro_index;
! 74:
! 75: /* A structure used to save nested macro strings.
! 76: It is a linked list of string/index for each saved macro. */
! 77: struct saved_macro {
! 78: struct saved_macro *next;
! 79: char *string;
! 80: int sindex;
! 81: };
! 82:
! 83: /* The list of saved macros. */
! 84: static struct saved_macro *macro_list = (struct saved_macro *)NULL;
! 85:
! 86: /* Set up to read subsequent input from STRING.
! 87: STRING is free ()'ed when we are done with it. */
! 88: void
! 89: _rl_with_macro_input (string)
! 90: char *string;
! 91: {
! 92: _rl_push_executing_macro ();
! 93: rl_executing_macro = string;
! 94: executing_macro_index = 0;
! 95: RL_SETSTATE(RL_STATE_MACROINPUT);
! 96: }
! 97:
! 98: /* Return the next character available from a macro, or 0 if
! 99: there are no macro characters. */
! 100: int
! 101: _rl_next_macro_key ()
! 102: {
! 103: int c;
! 104:
! 105: if (rl_executing_macro == 0)
! 106: return (0);
! 107:
! 108: if (rl_executing_macro[executing_macro_index] == 0)
! 109: {
! 110: _rl_pop_executing_macro ();
! 111: return (_rl_next_macro_key ());
! 112: }
! 113:
! 114: #if defined (READLINE_CALLBACKS)
! 115: c = rl_executing_macro[executing_macro_index++];
! 116: if (RL_ISSTATE (RL_STATE_CALLBACK) && RL_ISSTATE (RL_STATE_READCMD|RL_STATE_MOREINPUT) && rl_executing_macro[executing_macro_index] == 0)
! 117: _rl_pop_executing_macro ();
! 118: return c;
! 119: #else
! 120: return (rl_executing_macro[executing_macro_index++]);
! 121: #endif
! 122: }
! 123:
! 124: int
! 125: _rl_prev_macro_key ()
! 126: {
! 127: if (rl_executing_macro == 0)
! 128: return (0);
! 129:
! 130: if (executing_macro_index == 0)
! 131: return (0);
! 132:
! 133: executing_macro_index--;
! 134: return (rl_executing_macro[executing_macro_index]);
! 135: }
! 136:
! 137: /* Save the currently executing macro on a stack of saved macros. */
! 138: void
! 139: _rl_push_executing_macro ()
! 140: {
! 141: struct saved_macro *saver;
! 142:
! 143: saver = (struct saved_macro *)xmalloc (sizeof (struct saved_macro));
! 144: saver->next = macro_list;
! 145: saver->sindex = executing_macro_index;
! 146: saver->string = rl_executing_macro;
! 147:
! 148: macro_list = saver;
! 149: }
! 150:
! 151: /* Discard the current macro, replacing it with the one
! 152: on the top of the stack of saved macros. */
! 153: void
! 154: _rl_pop_executing_macro ()
! 155: {
! 156: struct saved_macro *macro;
! 157:
! 158: FREE (rl_executing_macro);
! 159: rl_executing_macro = (char *)NULL;
! 160: executing_macro_index = 0;
! 161:
! 162: if (macro_list)
! 163: {
! 164: macro = macro_list;
! 165: rl_executing_macro = macro_list->string;
! 166: executing_macro_index = macro_list->sindex;
! 167: macro_list = macro_list->next;
! 168: xfree (macro);
! 169: }
! 170:
! 171: if (rl_executing_macro == 0)
! 172: RL_UNSETSTATE(RL_STATE_MACROINPUT);
! 173: }
! 174:
! 175: /* Add a character to the macro being built. */
! 176: void
! 177: _rl_add_macro_char (c)
! 178: int c;
! 179: {
! 180: if (current_macro_index + 1 >= current_macro_size)
! 181: {
! 182: if (current_macro == 0)
! 183: current_macro = (char *)xmalloc (current_macro_size = 25);
! 184: else
! 185: current_macro = (char *)xrealloc (current_macro, current_macro_size += 25);
! 186: }
! 187:
! 188: current_macro[current_macro_index++] = c;
! 189: current_macro[current_macro_index] = '\0';
! 190: }
! 191:
! 192: void
! 193: _rl_kill_kbd_macro ()
! 194: {
! 195: if (current_macro)
! 196: {
! 197: xfree (current_macro);
! 198: current_macro = (char *) NULL;
! 199: }
! 200: current_macro_size = current_macro_index = 0;
! 201:
! 202: FREE (rl_executing_macro);
! 203: rl_executing_macro = (char *) NULL;
! 204: executing_macro_index = 0;
! 205:
! 206: RL_UNSETSTATE(RL_STATE_MACRODEF);
! 207: }
! 208:
! 209: /* Begin defining a keyboard macro.
! 210: Keystrokes are recorded as they are executed.
! 211: End the definition with rl_end_kbd_macro ().
! 212: If a numeric argument was explicitly typed, then append this
! 213: definition to the end of the existing macro, and start by
! 214: re-executing the existing macro. */
! 215: int
! 216: rl_start_kbd_macro (ignore1, ignore2)
! 217: int ignore1, ignore2;
! 218: {
! 219: if (RL_ISSTATE (RL_STATE_MACRODEF))
! 220: {
! 221: _rl_abort_internal ();
! 222: return -1;
! 223: }
! 224:
! 225: if (rl_explicit_arg)
! 226: {
! 227: if (current_macro)
! 228: _rl_with_macro_input (savestring (current_macro));
! 229: }
! 230: else
! 231: current_macro_index = 0;
! 232:
! 233: RL_SETSTATE(RL_STATE_MACRODEF);
! 234: return 0;
! 235: }
! 236:
! 237: /* Stop defining a keyboard macro.
! 238: A numeric argument says to execute the macro right now,
! 239: that many times, counting the definition as the first time. */
! 240: int
! 241: rl_end_kbd_macro (count, ignore)
! 242: int count, ignore;
! 243: {
! 244: if (RL_ISSTATE (RL_STATE_MACRODEF) == 0)
! 245: {
! 246: _rl_abort_internal ();
! 247: return -1;
! 248: }
! 249:
! 250: current_macro_index -= rl_key_sequence_length;
! 251: current_macro[current_macro_index] = '\0';
! 252:
! 253: RL_UNSETSTATE(RL_STATE_MACRODEF);
! 254:
! 255: return (rl_call_last_kbd_macro (--count, 0));
! 256: }
! 257:
! 258: /* Execute the most recently defined keyboard macro.
! 259: COUNT says how many times to execute it. */
! 260: int
! 261: rl_call_last_kbd_macro (count, ignore)
! 262: int count, ignore;
! 263: {
! 264: if (current_macro == 0)
! 265: _rl_abort_internal ();
! 266:
! 267: if (RL_ISSTATE (RL_STATE_MACRODEF))
! 268: {
! 269: rl_ding (); /* no recursive macros */
! 270: current_macro[--current_macro_index] = '\0'; /* erase this char */
! 271: return 0;
! 272: }
! 273:
! 274: while (count--)
! 275: _rl_with_macro_input (savestring (current_macro));
! 276: return 0;
! 277: }
! 278:
! 279: int
! 280: rl_print_last_kbd_macro (count, ignore)
! 281: int count, ignore;
! 282: {
! 283: char *m;
! 284:
! 285: if (current_macro == 0)
! 286: {
! 287: rl_ding ();
! 288: return 0;
! 289: }
! 290: m = _rl_untranslate_macro_value (current_macro, 1);
! 291: rl_crlf ();
! 292: printf ("%s", m);
! 293: fflush (stdout);
! 294: rl_crlf ();
! 295: FREE (m);
! 296: rl_forced_update_display ();
! 297: rl_display_fixed = 1;
! 298:
! 299: return 0;
! 300: }
! 301:
! 302: void
! 303: rl_push_macro_input (macro)
! 304: char *macro;
! 305: {
! 306: _rl_with_macro_input (macro);
! 307: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>