source: trunk/third/readline/macro.c @ 12992

Revision 12992, 6.9 KB checked in by kcr, 26 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r12991, which included commits to RCS files with non-trunk default branches.
Line 
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 1, 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   675 Mass Ave, Cambridge, MA 02139, 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#define SWAP(s, e)  do { int t; t = s; s = e; e = t; } while (0)
50
51/* Forward definitions. */
52void _rl_push_executing_macro (), _rl_pop_executing_macro ();
53void _rl_add_macro_char ();
54
55/* Extern declarations. */
56extern int rl_explicit_arg;
57extern int rl_key_sequence_length;
58
59extern void _rl_abort_internal ();
60
61extern char *xmalloc (), *xrealloc ();
62
63/* **************************************************************** */
64/*                                                                  */
65/*                      Hacking Keyboard Macros                     */
66/*                                                                  */
67/* **************************************************************** */
68
69/* Non-zero means to save keys that we dispatch on in a kbd macro. */
70int _rl_defining_kbd_macro = 0;
71
72/* The currently executing macro string.  If this is non-zero,
73   then it is a malloc ()'ed string where input is coming from. */
74char *_rl_executing_macro = (char *)NULL;
75
76/* The offset in the above string to the next character to be read. */
77static int executing_macro_index;
78
79/* The current macro string being built.  Characters get stuffed
80   in here by add_macro_char (). */
81static char *current_macro = (char *)NULL;
82
83/* The size of the buffer allocated to current_macro. */
84static int current_macro_size;
85
86/* The index at which characters are being added to current_macro. */
87static int current_macro_index;
88
89/* A structure used to save nested macro strings.
90   It is a linked list of string/index for each saved macro. */
91struct saved_macro {
92  struct saved_macro *next;
93  char *string;
94  int sindex;
95};
96
97/* The list of saved macros. */
98static struct saved_macro *macro_list = (struct saved_macro *)NULL;
99
100/* Set up to read subsequent input from STRING.
101   STRING is free ()'ed when we are done with it. */
102void
103_rl_with_macro_input (string)
104     char *string;
105{
106  _rl_push_executing_macro ();
107  _rl_executing_macro = string;
108  executing_macro_index = 0;
109}
110
111/* Return the next character available from a macro, or 0 if
112   there are no macro characters. */
113int
114_rl_next_macro_key ()
115{
116  if (_rl_executing_macro == 0)
117    return (0);
118
119  if (_rl_executing_macro[executing_macro_index] == 0)
120    {
121      _rl_pop_executing_macro ();
122      return (_rl_next_macro_key ());
123    }
124
125  return (_rl_executing_macro[executing_macro_index++]);
126}
127
128/* Save the currently executing macro on a stack of saved macros. */
129void
130_rl_push_executing_macro ()
131{
132  struct saved_macro *saver;
133
134  saver = (struct saved_macro *)xmalloc (sizeof (struct saved_macro));
135  saver->next = macro_list;
136  saver->sindex = executing_macro_index;
137  saver->string = _rl_executing_macro;
138
139  macro_list = saver;
140}
141
142/* Discard the current macro, replacing it with the one
143   on the top of the stack of saved macros. */
144void
145_rl_pop_executing_macro ()
146{
147  struct saved_macro *macro;
148
149  if (_rl_executing_macro)
150    free (_rl_executing_macro);
151
152  _rl_executing_macro = (char *)NULL;
153  executing_macro_index = 0;
154
155  if (macro_list)
156    {
157      macro = macro_list;
158      _rl_executing_macro = macro_list->string;
159      executing_macro_index = macro_list->sindex;
160      macro_list = macro_list->next;
161      free (macro);
162    }
163}
164
165/* Add a character to the macro being built. */
166void
167_rl_add_macro_char (c)
168     int c;
169{
170  if (current_macro_index + 1 >= current_macro_size)
171    {
172      if (current_macro == 0)
173        current_macro = xmalloc (current_macro_size = 25);
174      else
175        current_macro = xrealloc (current_macro, current_macro_size += 25);
176    }
177
178  current_macro[current_macro_index++] = c;
179  current_macro[current_macro_index] = '\0';
180}
181
182void
183_rl_kill_kbd_macro ()
184{
185  if (current_macro)
186    {
187      free (current_macro);
188      current_macro = (char *) NULL;
189    }
190  current_macro_size = current_macro_index = 0;
191
192  if (_rl_executing_macro)
193    {
194      free (_rl_executing_macro);
195      _rl_executing_macro = (char *) NULL;
196    }
197  executing_macro_index = 0;
198
199  _rl_defining_kbd_macro = 0;
200}
201
202/* Begin defining a keyboard macro.
203   Keystrokes are recorded as they are executed.
204   End the definition with rl_end_kbd_macro ().
205   If a numeric argument was explicitly typed, then append this
206   definition to the end of the existing macro, and start by
207   re-executing the existing macro. */
208int
209rl_start_kbd_macro (ignore1, ignore2)
210     int ignore1, ignore2;
211{
212  if (_rl_defining_kbd_macro)
213    {
214      _rl_abort_internal ();
215      return -1;
216    }
217
218  if (rl_explicit_arg)
219    {
220      if (current_macro)
221        _rl_with_macro_input (savestring (current_macro));
222    }
223  else
224    current_macro_index = 0;
225
226  _rl_defining_kbd_macro = 1;
227  return 0;
228}
229
230/* Stop defining a keyboard macro.
231   A numeric argument says to execute the macro right now,
232   that many times, counting the definition as the first time. */
233int
234rl_end_kbd_macro (count, ignore)
235     int count, ignore;
236{
237  if (_rl_defining_kbd_macro == 0)
238    {
239      _rl_abort_internal ();
240      return -1;
241    }
242
243  current_macro_index -= rl_key_sequence_length - 1;
244  current_macro[current_macro_index] = '\0';
245
246  _rl_defining_kbd_macro = 0;
247
248  return (rl_call_last_kbd_macro (--count, 0));
249}
250
251/* Execute the most recently defined keyboard macro.
252   COUNT says how many times to execute it. */
253int
254rl_call_last_kbd_macro (count, ignore)
255     int count, ignore;
256{
257  if (current_macro == 0)
258    _rl_abort_internal ();
259
260  if (_rl_defining_kbd_macro)
261    {
262      ding ();          /* no recursive macros */
263      current_macro[--current_macro_index] = '\0';      /* erase this char */
264      return 0;
265    }
266
267  while (count--)
268    _rl_with_macro_input (savestring (current_macro));
269  return 0;
270}
271
272void
273rl_push_macro_input (macro)
274     char *macro;
275{
276  _rl_with_macro_input (macro);
277}
Note: See TracBrowser for help on using the repository browser.