#define READLINE_LIBRARY
#if defined (HAVE_CONFIG_H)
# include <config.h>
#endif
#include <sys/types.h>
#if defined (HAVE_UNISTD_H)
# include <unistd.h>
#endif
#if defined (HAVE_STDLIB_H)
# include <stdlib.h>
#else
# include "ansi_stdlib.h"
#endif
#include <stdio.h>
#include "rldefs.h"
#include "readline.h"
#include "history.h"
#include "rlprivate.h"
#include "xmalloc.h"
char *rl_executing_macro = (char *)NULL;
static int executing_macro_index;
static char *current_macro = (char *)NULL;
static int current_macro_size;
static int current_macro_index;
struct saved_macro {
struct saved_macro *next;
char *string;
int sindex;
};
static struct saved_macro *macro_list = (struct saved_macro *)NULL;
void
_rl_with_macro_input (string)
char *string;
{
_rl_push_executing_macro ();
rl_executing_macro = string;
executing_macro_index = 0;
RL_SETSTATE(RL_STATE_MACROINPUT);
}
int
_rl_next_macro_key ()
{
int c;
if (rl_executing_macro == 0)
return (0);
if (rl_executing_macro[executing_macro_index] == 0)
{
_rl_pop_executing_macro ();
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
return (rl_executing_macro[executing_macro_index++]);
#endif
}
void
_rl_push_executing_macro ()
{
struct saved_macro *saver;
saver = (struct saved_macro *)xmalloc (sizeof (struct saved_macro));
saver->next = macro_list;
saver->sindex = executing_macro_index;
saver->string = rl_executing_macro;
macro_list = saver;
}
void
_rl_pop_executing_macro ()
{
struct saved_macro *macro;
FREE (rl_executing_macro);
rl_executing_macro = (char *)NULL;
executing_macro_index = 0;
if (macro_list)
{
macro = macro_list;
rl_executing_macro = macro_list->string;
executing_macro_index = macro_list->sindex;
macro_list = macro_list->next;
free (macro);
}
if (rl_executing_macro == 0)
RL_UNSETSTATE(RL_STATE_MACROINPUT);
}
void
_rl_add_macro_char (c)
int c;
{
if (current_macro_index + 1 >= current_macro_size)
{
if (current_macro == 0)
current_macro = (char *)xmalloc (current_macro_size = 25);
else
current_macro = (char *)xrealloc (current_macro, current_macro_size += 25);
}
current_macro[current_macro_index++] = c;
current_macro[current_macro_index] = '\0';
}
void
_rl_kill_kbd_macro ()
{
if (current_macro)
{
free (current_macro);
current_macro = (char *) NULL;
}
current_macro_size = current_macro_index = 0;
FREE (rl_executing_macro);
rl_executing_macro = (char *) NULL;
executing_macro_index = 0;
RL_UNSETSTATE(RL_STATE_MACRODEF);
}
int
rl_start_kbd_macro (ignore1, ignore2)
int ignore1, ignore2;
{
if (RL_ISSTATE (RL_STATE_MACRODEF))
{
_rl_abort_internal ();
return -1;
}
if (rl_explicit_arg)
{
if (current_macro)
_rl_with_macro_input (savestring (current_macro));
}
else
current_macro_index = 0;
RL_SETSTATE(RL_STATE_MACRODEF);
return 0;
}
int
rl_end_kbd_macro (count, ignore)
int count, ignore;
{
if (RL_ISSTATE (RL_STATE_MACRODEF) == 0)
{
_rl_abort_internal ();
return -1;
}
current_macro_index -= rl_key_sequence_length - 1;
current_macro[current_macro_index] = '\0';
RL_UNSETSTATE(RL_STATE_MACRODEF);
return (rl_call_last_kbd_macro (--count, 0));
}
int
rl_call_last_kbd_macro (count, ignore)
int count, ignore;
{
if (current_macro == 0)
_rl_abort_internal ();
if (RL_ISSTATE (RL_STATE_MACRODEF))
{
rl_ding ();
current_macro[--current_macro_index] = '\0';
return 0;
}
while (count--)
_rl_with_macro_input (savestring (current_macro));
return 0;
}
void
rl_push_macro_input (macro)
char *macro;
{
_rl_with_macro_input (macro);
}