/* macro.c -- keyboard macros for readline. */
-/* Copyright (C) 1994 Free Software Foundation, Inc.
+/* Copyright (C) 1994-2009,2017 Free Software Foundation, Inc.
- This file is part of the GNU Readline Library, a library for
- reading lines of text with interactive input and history editing.
+ This file is part of the GNU Readline Library (Readline), a library
+ for reading lines of text with interactive input and history editing.
- The GNU Readline Library is free software; you can redistribute it
- and/or modify it under the terms of the GNU General Public License
- as published by the Free Software Foundation; either version 2, or
+ Readline is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
- The GNU Readline Library is distributed in the hope that it will be
- useful, but WITHOUT ANY WARRANTY; without even the implied warranty
- of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ Readline is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
- The GNU General Public License is often shipped with GNU software, and
- is generally kept in a file called COPYING or LICENSE. If you do not
- have a copy of the license, write to the Free Software Foundation,
- 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
+ You should have received a copy of the GNU General Public License
+ along with Readline. If not, see <http://www.gnu.org/licenses/>.
+*/
+
#define READLINE_LIBRARY
#if defined (HAVE_CONFIG_H)
#include "rlprivate.h"
#include "xmalloc.h"
+#define MAX_MACRO_LEVEL 16
+
/* **************************************************************** */
/* */
/* Hacking Keyboard Macros */
/* The list of saved macros. */
static struct saved_macro *macro_list = (struct saved_macro *)NULL;
+static int macro_level = 0;
+
/* Set up to read subsequent input from STRING.
STRING is free ()'ed when we are done with it. */
void
-_rl_with_macro_input (string)
- char *string;
+_rl_with_macro_input (char *string)
{
- _rl_push_executing_macro ();
+ if (macro_level > MAX_MACRO_LEVEL)
+ {
+ _rl_errmsg ("maximum macro execution nesting level exceeded");
+ _rl_abort_internal ();
+ return;
+ }
+
+#if 0
+ if (rl_executing_macro) /* XXX - later */
+#endif
+ _rl_push_executing_macro ();
rl_executing_macro = string;
executing_macro_index = 0;
RL_SETSTATE(RL_STATE_MACROINPUT);
/* Return the next character available from a macro, or 0 if
there are no macro characters. */
int
-_rl_next_macro_key ()
+_rl_next_macro_key (void)
{
+ int c;
+
if (rl_executing_macro == 0)
return (0);
return (_rl_next_macro_key ());
}
+#if defined (READLINE_CALLBACKS)
+ c = rl_executing_macro[executing_macro_index++];
+ if (RL_ISSTATE (RL_STATE_CALLBACK) && RL_ISSTATE (RL_STATE_READCMD|RL_STATE_MOREINPUT) && rl_executing_macro[executing_macro_index] == 0)
+ _rl_pop_executing_macro ();
+ return c;
+#else
+ /* XXX - consider doing the same as the callback code, just not testing
+ whether we're running in callback mode */
return (rl_executing_macro[executing_macro_index++]);
+#endif
+}
+
+int
+_rl_peek_macro_key (void)
+{
+ if (rl_executing_macro == 0)
+ return (0);
+ if (rl_executing_macro[executing_macro_index] == 0 && (macro_list == 0 || macro_list->string == 0))
+ return (0);
+ if (rl_executing_macro[executing_macro_index] == 0 && macro_list && macro_list->string)
+ return (macro_list->string[0]);
+ return (rl_executing_macro[executing_macro_index]);
+}
+
+int
+_rl_prev_macro_key (void)
+{
+ if (rl_executing_macro == 0)
+ return (0);
+
+ if (executing_macro_index == 0)
+ return (0);
+
+ executing_macro_index--;
+ return (rl_executing_macro[executing_macro_index]);
}
/* Save the currently executing macro on a stack of saved macros. */
void
-_rl_push_executing_macro ()
+_rl_push_executing_macro (void)
{
struct saved_macro *saver;
saver->string = rl_executing_macro;
macro_list = saver;
+
+ macro_level++;
}
/* Discard the current macro, replacing it with the one
on the top of the stack of saved macros. */
void
-_rl_pop_executing_macro ()
+_rl_pop_executing_macro (void)
{
struct saved_macro *macro;
rl_executing_macro = macro_list->string;
executing_macro_index = macro_list->sindex;
macro_list = macro_list->next;
- free (macro);
+ xfree (macro);
}
+ macro_level--;
+
if (rl_executing_macro == 0)
RL_UNSETSTATE(RL_STATE_MACROINPUT);
}
/* Add a character to the macro being built. */
void
-_rl_add_macro_char (c)
- int c;
+_rl_add_macro_char (int c)
{
if (current_macro_index + 1 >= current_macro_size)
{
}
void
-_rl_kill_kbd_macro ()
+_rl_kill_kbd_macro (void)
{
if (current_macro)
{
- free (current_macro);
+ xfree (current_macro);
current_macro = (char *) NULL;
}
current_macro_size = current_macro_index = 0;
definition to the end of the existing macro, and start by
re-executing the existing macro. */
int
-rl_start_kbd_macro (ignore1, ignore2)
- int ignore1, ignore2;
+rl_start_kbd_macro (int ignore1, int ignore2)
{
if (RL_ISSTATE (RL_STATE_MACRODEF))
{
_rl_abort_internal ();
- return -1;
+ return 1;
}
if (rl_explicit_arg)
A numeric argument says to execute the macro right now,
that many times, counting the definition as the first time. */
int
-rl_end_kbd_macro (count, ignore)
- int count, ignore;
+rl_end_kbd_macro (int count, int ignore)
{
if (RL_ISSTATE (RL_STATE_MACRODEF) == 0)
{
_rl_abort_internal ();
- return -1;
+ return 1;
}
- current_macro_index -= rl_key_sequence_length - 1;
+ current_macro_index -= rl_key_sequence_length;
current_macro[current_macro_index] = '\0';
RL_UNSETSTATE(RL_STATE_MACRODEF);
/* Execute the most recently defined keyboard macro.
COUNT says how many times to execute it. */
int
-rl_call_last_kbd_macro (count, ignore)
- int count, ignore;
+rl_call_last_kbd_macro (int count, int ignore)
{
if (current_macro == 0)
_rl_abort_internal ();
return 0;
}
+int
+rl_print_last_kbd_macro (int count, int ignore)
+{
+ char *m;
+
+ if (current_macro == 0)
+ {
+ rl_ding ();
+ return 0;
+ }
+ m = _rl_untranslate_macro_value (current_macro, 1);
+ rl_crlf ();
+ printf ("%s", m);
+ fflush (stdout);
+ rl_crlf ();
+ FREE (m);
+ rl_forced_update_display ();
+ rl_display_fixed = 1;
+
+ return 0;
+}
+
void
-rl_push_macro_input (macro)
- char *macro;
+rl_push_macro_input (char *macro)
{
_rl_with_macro_input (macro);
}