xref: /openbsd/gnu/lib/libreadline/macro.c (revision 9704b281)
1 /* macro.c -- keyboard macros for readline. */
2 
3 /* Copyright (C) 1994 Free Software Foundation, Inc.
4 
5    This file is part of the GNU Readline Library, a library for
6    reading lines of text with interactive input and history editing.
7 
8    The GNU Readline Library is free software; you can redistribute it
9    and/or modify it under the terms of the GNU General Public License
10    as published by the Free Software Foundation; either version 2, or
11    (at your option) any later version.
12 
13    The GNU Readline Library is distributed in the hope that it will be
14    useful, but WITHOUT ANY WARRANTY; without even the implied warranty
15    of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17 
18    The GNU General Public License is often shipped with GNU software, and
19    is generally kept in a file called COPYING or LICENSE.  If you do not
20    have a copy of the license, write to the Free Software Foundation,
21    59 Temple Place, Suite 330, Boston, MA 02111 USA. */
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
_rl_with_macro_input(string)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
_rl_next_macro_key()101 _rl_next_macro_key ()
102 {
103   if (rl_executing_macro == 0)
104     return (0);
105 
106   if (rl_executing_macro[executing_macro_index] == 0)
107     {
108       _rl_pop_executing_macro ();
109       return (_rl_next_macro_key ());
110     }
111 
112   return (rl_executing_macro[executing_macro_index++]);
113 }
114 
115 /* Save the currently executing macro on a stack of saved macros. */
116 void
_rl_push_executing_macro()117 _rl_push_executing_macro ()
118 {
119   struct saved_macro *saver;
120 
121   saver = (struct saved_macro *)xmalloc (sizeof (struct saved_macro));
122   saver->next = macro_list;
123   saver->sindex = executing_macro_index;
124   saver->string = rl_executing_macro;
125 
126   macro_list = saver;
127 }
128 
129 /* Discard the current macro, replacing it with the one
130    on the top of the stack of saved macros. */
131 void
_rl_pop_executing_macro()132 _rl_pop_executing_macro ()
133 {
134   struct saved_macro *macro;
135 
136   FREE (rl_executing_macro);
137   rl_executing_macro = (char *)NULL;
138   executing_macro_index = 0;
139 
140   if (macro_list)
141     {
142       macro = macro_list;
143       rl_executing_macro = macro_list->string;
144       executing_macro_index = macro_list->sindex;
145       macro_list = macro_list->next;
146       free (macro);
147     }
148 
149   if (rl_executing_macro == 0)
150     RL_UNSETSTATE(RL_STATE_MACROINPUT);
151 }
152 
153 /* Add a character to the macro being built. */
154 void
_rl_add_macro_char(c)155 _rl_add_macro_char (c)
156      int c;
157 {
158   if (current_macro_index + 1 >= current_macro_size)
159     {
160       if (current_macro == 0)
161 	current_macro = (char *)xmalloc (current_macro_size = 25);
162       else
163 	current_macro = (char *)xrealloc (current_macro, current_macro_size += 25);
164     }
165 
166   current_macro[current_macro_index++] = c;
167   current_macro[current_macro_index] = '\0';
168 }
169 
170 void
_rl_kill_kbd_macro()171 _rl_kill_kbd_macro ()
172 {
173   if (current_macro)
174     {
175       free (current_macro);
176       current_macro = (char *) NULL;
177     }
178   current_macro_size = current_macro_index = 0;
179 
180   FREE (rl_executing_macro);
181   rl_executing_macro = (char *) NULL;
182   executing_macro_index = 0;
183 
184   RL_UNSETSTATE(RL_STATE_MACRODEF);
185 }
186 
187 /* Begin defining a keyboard macro.
188    Keystrokes are recorded as they are executed.
189    End the definition with rl_end_kbd_macro ().
190    If a numeric argument was explicitly typed, then append this
191    definition to the end of the existing macro, and start by
192    re-executing the existing macro. */
193 int
rl_start_kbd_macro(ignore1,ignore2)194 rl_start_kbd_macro (ignore1, ignore2)
195      int ignore1, ignore2;
196 {
197   if (RL_ISSTATE (RL_STATE_MACRODEF))
198     {
199       _rl_abort_internal ();
200       return -1;
201     }
202 
203   if (rl_explicit_arg)
204     {
205       if (current_macro)
206 	_rl_with_macro_input (savestring (current_macro));
207     }
208   else
209     current_macro_index = 0;
210 
211   RL_SETSTATE(RL_STATE_MACRODEF);
212   return 0;
213 }
214 
215 /* Stop defining a keyboard macro.
216    A numeric argument says to execute the macro right now,
217    that many times, counting the definition as the first time. */
218 int
rl_end_kbd_macro(count,ignore)219 rl_end_kbd_macro (count, ignore)
220      int count, ignore;
221 {
222   if (RL_ISSTATE (RL_STATE_MACRODEF) == 0)
223     {
224       _rl_abort_internal ();
225       return -1;
226     }
227 
228   current_macro_index -= rl_key_sequence_length - 1;
229   current_macro[current_macro_index] = '\0';
230 
231   RL_UNSETSTATE(RL_STATE_MACRODEF);
232 
233   return (rl_call_last_kbd_macro (--count, 0));
234 }
235 
236 /* Execute the most recently defined keyboard macro.
237    COUNT says how many times to execute it. */
238 int
rl_call_last_kbd_macro(count,ignore)239 rl_call_last_kbd_macro (count, ignore)
240      int count, ignore;
241 {
242   if (current_macro == 0)
243     _rl_abort_internal ();
244 
245   if (RL_ISSTATE (RL_STATE_MACRODEF))
246     {
247       rl_ding ();		/* no recursive macros */
248       current_macro[--current_macro_index] = '\0';	/* erase this char */
249       return 0;
250     }
251 
252   while (count--)
253     _rl_with_macro_input (savestring (current_macro));
254   return 0;
255 }
256 
257 void
rl_push_macro_input(macro)258 rl_push_macro_input (macro)
259      char *macro;
260 {
261   _rl_with_macro_input (macro);
262 }
263