xref: /openbsd-src/gnu/lib/libreadline/macro.c (revision 1acd27e7bc206a851db8939b2c80b39478e406c3)
1*1acd27e7Smillert /* macro.c -- keyboard macros for readline. */
2*1acd27e7Smillert 
3*1acd27e7Smillert /* Copyright (C) 1994 Free Software Foundation, Inc.
4*1acd27e7Smillert 
5*1acd27e7Smillert    This file is part of the GNU Readline Library, a library for
6*1acd27e7Smillert    reading lines of text with interactive input and history editing.
7*1acd27e7Smillert 
8*1acd27e7Smillert    The GNU Readline Library is free software; you can redistribute it
9*1acd27e7Smillert    and/or modify it under the terms of the GNU General Public License
10*1acd27e7Smillert    as published by the Free Software Foundation; either version 2, or
11*1acd27e7Smillert    (at your option) any later version.
12*1acd27e7Smillert 
13*1acd27e7Smillert    The GNU Readline Library is distributed in the hope that it will be
14*1acd27e7Smillert    useful, but WITHOUT ANY WARRANTY; without even the implied warranty
15*1acd27e7Smillert    of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16*1acd27e7Smillert    GNU General Public License for more details.
17*1acd27e7Smillert 
18*1acd27e7Smillert    The GNU General Public License is often shipped with GNU software, and
19*1acd27e7Smillert    is generally kept in a file called COPYING or LICENSE.  If you do not
20*1acd27e7Smillert    have a copy of the license, write to the Free Software Foundation,
21*1acd27e7Smillert    59 Temple Place, Suite 330, Boston, MA 02111 USA. */
22*1acd27e7Smillert #define READLINE_LIBRARY
23*1acd27e7Smillert 
24*1acd27e7Smillert #if defined (HAVE_CONFIG_H)
25*1acd27e7Smillert #  include <config.h>
26*1acd27e7Smillert #endif
27*1acd27e7Smillert 
28*1acd27e7Smillert #include <sys/types.h>
29*1acd27e7Smillert 
30*1acd27e7Smillert #if defined (HAVE_UNISTD_H)
31*1acd27e7Smillert #  include <unistd.h>           /* for _POSIX_VERSION */
32*1acd27e7Smillert #endif /* HAVE_UNISTD_H */
33*1acd27e7Smillert 
34*1acd27e7Smillert #if defined (HAVE_STDLIB_H)
35*1acd27e7Smillert #  include <stdlib.h>
36*1acd27e7Smillert #else
37*1acd27e7Smillert #  include "ansi_stdlib.h"
38*1acd27e7Smillert #endif /* HAVE_STDLIB_H */
39*1acd27e7Smillert 
40*1acd27e7Smillert #include <stdio.h>
41*1acd27e7Smillert 
42*1acd27e7Smillert /* System-specific feature definitions and include files. */
43*1acd27e7Smillert #include "rldefs.h"
44*1acd27e7Smillert 
45*1acd27e7Smillert /* Some standard library routines. */
46*1acd27e7Smillert #include "readline.h"
47*1acd27e7Smillert #include "history.h"
48*1acd27e7Smillert 
49*1acd27e7Smillert #include "rlprivate.h"
50*1acd27e7Smillert #include "xmalloc.h"
51*1acd27e7Smillert 
52*1acd27e7Smillert #define SWAP(s, e)  do { int t; t = s; s = e; e = t; } while (0)
53*1acd27e7Smillert 
54*1acd27e7Smillert /* **************************************************************** */
55*1acd27e7Smillert /*								    */
56*1acd27e7Smillert /*			Hacking Keyboard Macros 		    */
57*1acd27e7Smillert /*								    */
58*1acd27e7Smillert /* **************************************************************** */
59*1acd27e7Smillert 
60*1acd27e7Smillert /* Non-zero means to save keys that we dispatch on in a kbd macro. */
61*1acd27e7Smillert int _rl_defining_kbd_macro = 0;
62*1acd27e7Smillert 
63*1acd27e7Smillert /* The currently executing macro string.  If this is non-zero,
64*1acd27e7Smillert    then it is a malloc ()'ed string where input is coming from. */
65*1acd27e7Smillert char *_rl_executing_macro = (char *)NULL;
66*1acd27e7Smillert 
67*1acd27e7Smillert /* The offset in the above string to the next character to be read. */
68*1acd27e7Smillert static int executing_macro_index;
69*1acd27e7Smillert 
70*1acd27e7Smillert /* The current macro string being built.  Characters get stuffed
71*1acd27e7Smillert    in here by add_macro_char (). */
72*1acd27e7Smillert static char *current_macro = (char *)NULL;
73*1acd27e7Smillert 
74*1acd27e7Smillert /* The size of the buffer allocated to current_macro. */
75*1acd27e7Smillert static int current_macro_size;
76*1acd27e7Smillert 
77*1acd27e7Smillert /* The index at which characters are being added to current_macro. */
78*1acd27e7Smillert static int current_macro_index;
79*1acd27e7Smillert 
80*1acd27e7Smillert /* A structure used to save nested macro strings.
81*1acd27e7Smillert    It is a linked list of string/index for each saved macro. */
82*1acd27e7Smillert struct saved_macro {
83*1acd27e7Smillert   struct saved_macro *next;
84*1acd27e7Smillert   char *string;
85*1acd27e7Smillert   int sindex;
86*1acd27e7Smillert };
87*1acd27e7Smillert 
88*1acd27e7Smillert /* The list of saved macros. */
89*1acd27e7Smillert static struct saved_macro *macro_list = (struct saved_macro *)NULL;
90*1acd27e7Smillert 
91*1acd27e7Smillert /* Set up to read subsequent input from STRING.
92*1acd27e7Smillert    STRING is free ()'ed when we are done with it. */
93*1acd27e7Smillert void
94*1acd27e7Smillert _rl_with_macro_input (string)
95*1acd27e7Smillert      char *string;
96*1acd27e7Smillert {
97*1acd27e7Smillert   _rl_push_executing_macro ();
98*1acd27e7Smillert   _rl_executing_macro = string;
99*1acd27e7Smillert   executing_macro_index = 0;
100*1acd27e7Smillert }
101*1acd27e7Smillert 
102*1acd27e7Smillert /* Return the next character available from a macro, or 0 if
103*1acd27e7Smillert    there are no macro characters. */
104*1acd27e7Smillert int
105*1acd27e7Smillert _rl_next_macro_key ()
106*1acd27e7Smillert {
107*1acd27e7Smillert   if (_rl_executing_macro == 0)
108*1acd27e7Smillert     return (0);
109*1acd27e7Smillert 
110*1acd27e7Smillert   if (_rl_executing_macro[executing_macro_index] == 0)
111*1acd27e7Smillert     {
112*1acd27e7Smillert       _rl_pop_executing_macro ();
113*1acd27e7Smillert       return (_rl_next_macro_key ());
114*1acd27e7Smillert     }
115*1acd27e7Smillert 
116*1acd27e7Smillert   return (_rl_executing_macro[executing_macro_index++]);
117*1acd27e7Smillert }
118*1acd27e7Smillert 
119*1acd27e7Smillert /* Save the currently executing macro on a stack of saved macros. */
120*1acd27e7Smillert void
121*1acd27e7Smillert _rl_push_executing_macro ()
122*1acd27e7Smillert {
123*1acd27e7Smillert   struct saved_macro *saver;
124*1acd27e7Smillert 
125*1acd27e7Smillert   saver = (struct saved_macro *)xmalloc (sizeof (struct saved_macro));
126*1acd27e7Smillert   saver->next = macro_list;
127*1acd27e7Smillert   saver->sindex = executing_macro_index;
128*1acd27e7Smillert   saver->string = _rl_executing_macro;
129*1acd27e7Smillert 
130*1acd27e7Smillert   macro_list = saver;
131*1acd27e7Smillert }
132*1acd27e7Smillert 
133*1acd27e7Smillert /* Discard the current macro, replacing it with the one
134*1acd27e7Smillert    on the top of the stack of saved macros. */
135*1acd27e7Smillert void
136*1acd27e7Smillert _rl_pop_executing_macro ()
137*1acd27e7Smillert {
138*1acd27e7Smillert   struct saved_macro *macro;
139*1acd27e7Smillert 
140*1acd27e7Smillert   if (_rl_executing_macro)
141*1acd27e7Smillert     free (_rl_executing_macro);
142*1acd27e7Smillert 
143*1acd27e7Smillert   _rl_executing_macro = (char *)NULL;
144*1acd27e7Smillert   executing_macro_index = 0;
145*1acd27e7Smillert 
146*1acd27e7Smillert   if (macro_list)
147*1acd27e7Smillert     {
148*1acd27e7Smillert       macro = macro_list;
149*1acd27e7Smillert       _rl_executing_macro = macro_list->string;
150*1acd27e7Smillert       executing_macro_index = macro_list->sindex;
151*1acd27e7Smillert       macro_list = macro_list->next;
152*1acd27e7Smillert       free (macro);
153*1acd27e7Smillert     }
154*1acd27e7Smillert }
155*1acd27e7Smillert 
156*1acd27e7Smillert /* Add a character to the macro being built. */
157*1acd27e7Smillert void
158*1acd27e7Smillert _rl_add_macro_char (c)
159*1acd27e7Smillert      int c;
160*1acd27e7Smillert {
161*1acd27e7Smillert   if (current_macro_index + 1 >= current_macro_size)
162*1acd27e7Smillert     {
163*1acd27e7Smillert       if (current_macro == 0)
164*1acd27e7Smillert 	current_macro = xmalloc (current_macro_size = 25);
165*1acd27e7Smillert       else
166*1acd27e7Smillert 	current_macro = xrealloc (current_macro, current_macro_size += 25);
167*1acd27e7Smillert     }
168*1acd27e7Smillert 
169*1acd27e7Smillert   current_macro[current_macro_index++] = c;
170*1acd27e7Smillert   current_macro[current_macro_index] = '\0';
171*1acd27e7Smillert }
172*1acd27e7Smillert 
173*1acd27e7Smillert void
174*1acd27e7Smillert _rl_kill_kbd_macro ()
175*1acd27e7Smillert {
176*1acd27e7Smillert   if (current_macro)
177*1acd27e7Smillert     {
178*1acd27e7Smillert       free (current_macro);
179*1acd27e7Smillert       current_macro = (char *) NULL;
180*1acd27e7Smillert     }
181*1acd27e7Smillert   current_macro_size = current_macro_index = 0;
182*1acd27e7Smillert 
183*1acd27e7Smillert   if (_rl_executing_macro)
184*1acd27e7Smillert     {
185*1acd27e7Smillert       free (_rl_executing_macro);
186*1acd27e7Smillert       _rl_executing_macro = (char *) NULL;
187*1acd27e7Smillert     }
188*1acd27e7Smillert   executing_macro_index = 0;
189*1acd27e7Smillert 
190*1acd27e7Smillert   _rl_defining_kbd_macro = 0;
191*1acd27e7Smillert }
192*1acd27e7Smillert 
193*1acd27e7Smillert /* Begin defining a keyboard macro.
194*1acd27e7Smillert    Keystrokes are recorded as they are executed.
195*1acd27e7Smillert    End the definition with rl_end_kbd_macro ().
196*1acd27e7Smillert    If a numeric argument was explicitly typed, then append this
197*1acd27e7Smillert    definition to the end of the existing macro, and start by
198*1acd27e7Smillert    re-executing the existing macro. */
199*1acd27e7Smillert int
200*1acd27e7Smillert rl_start_kbd_macro (ignore1, ignore2)
201*1acd27e7Smillert      int ignore1, ignore2;
202*1acd27e7Smillert {
203*1acd27e7Smillert   if (_rl_defining_kbd_macro)
204*1acd27e7Smillert     {
205*1acd27e7Smillert       _rl_abort_internal ();
206*1acd27e7Smillert       return -1;
207*1acd27e7Smillert     }
208*1acd27e7Smillert 
209*1acd27e7Smillert   if (rl_explicit_arg)
210*1acd27e7Smillert     {
211*1acd27e7Smillert       if (current_macro)
212*1acd27e7Smillert 	_rl_with_macro_input (savestring (current_macro));
213*1acd27e7Smillert     }
214*1acd27e7Smillert   else
215*1acd27e7Smillert     current_macro_index = 0;
216*1acd27e7Smillert 
217*1acd27e7Smillert   _rl_defining_kbd_macro = 1;
218*1acd27e7Smillert   return 0;
219*1acd27e7Smillert }
220*1acd27e7Smillert 
221*1acd27e7Smillert /* Stop defining a keyboard macro.
222*1acd27e7Smillert    A numeric argument says to execute the macro right now,
223*1acd27e7Smillert    that many times, counting the definition as the first time. */
224*1acd27e7Smillert int
225*1acd27e7Smillert rl_end_kbd_macro (count, ignore)
226*1acd27e7Smillert      int count, ignore;
227*1acd27e7Smillert {
228*1acd27e7Smillert   if (_rl_defining_kbd_macro == 0)
229*1acd27e7Smillert     {
230*1acd27e7Smillert       _rl_abort_internal ();
231*1acd27e7Smillert       return -1;
232*1acd27e7Smillert     }
233*1acd27e7Smillert 
234*1acd27e7Smillert   current_macro_index -= rl_key_sequence_length - 1;
235*1acd27e7Smillert   current_macro[current_macro_index] = '\0';
236*1acd27e7Smillert 
237*1acd27e7Smillert   _rl_defining_kbd_macro = 0;
238*1acd27e7Smillert 
239*1acd27e7Smillert   return (rl_call_last_kbd_macro (--count, 0));
240*1acd27e7Smillert }
241*1acd27e7Smillert 
242*1acd27e7Smillert /* Execute the most recently defined keyboard macro.
243*1acd27e7Smillert    COUNT says how many times to execute it. */
244*1acd27e7Smillert int
245*1acd27e7Smillert rl_call_last_kbd_macro (count, ignore)
246*1acd27e7Smillert      int count, ignore;
247*1acd27e7Smillert {
248*1acd27e7Smillert   if (current_macro == 0)
249*1acd27e7Smillert     _rl_abort_internal ();
250*1acd27e7Smillert 
251*1acd27e7Smillert   if (_rl_defining_kbd_macro)
252*1acd27e7Smillert     {
253*1acd27e7Smillert       ding ();		/* no recursive macros */
254*1acd27e7Smillert       current_macro[--current_macro_index] = '\0';	/* erase this char */
255*1acd27e7Smillert       return 0;
256*1acd27e7Smillert     }
257*1acd27e7Smillert 
258*1acd27e7Smillert   while (count--)
259*1acd27e7Smillert     _rl_with_macro_input (savestring (current_macro));
260*1acd27e7Smillert   return 0;
261*1acd27e7Smillert }
262*1acd27e7Smillert 
263*1acd27e7Smillert void
264*1acd27e7Smillert rl_push_macro_input (macro)
265*1acd27e7Smillert      char *macro;
266*1acd27e7Smillert {
267*1acd27e7Smillert   _rl_with_macro_input (macro);
268*1acd27e7Smillert }
269