home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Frozen Fish 1: Amiga
/
FrozenFish-Apr94.iso
/
bbs
/
alib
/
d3xx
/
d352
/
mg.lha
/
MG
/
src.LZH
/
mg
/
macro.c
< prev
next >
Wrap
C/C++ Source or Header
|
1990-05-23
|
8KB
|
395 lines
/* keyboard macros for MicroGnuEmacs 3a */
#include "no_macro.h"
#ifndef NO_MACRO
#include "fkeys.h"
#include "def.h"
#include "macro.h"
#include "key.h"
#ifdef ANSI
#include <stdlib.h>
#include <string.h>
#endif
/* KBD macro grows by MGROWSIZE macros at a time */
#define MGROWSIZE 50
int macrodef;
struct macro *inmacro = NULL;
struct macro kbdmacro;
static struct macro savemac; /* Place to put macro being defined */
static int growmacro
PROTO((struct macro *));
static struct macro *makemacro
PROTO((char *, KCHAR *, int));
static int finsert
PROTO((KCHAR));
/* ARGSUSED */
definemacro(f, n)
int f, n;
{
if (macrodef) {
ewprintf("Already defining macro!");
return macrodef = FALSE;
}
savemac = kbdmacro;
kbdmacro.m_max = kbdmacro.m_count = 0;
kbdmacro.m_text = NULL;
ewprintf("Defining Keyboard Macro...");
return macrodef = TRUE;
}
/* ARGSUSED */
finishmacro(f, n)
int f, n;
{
if (inmacro)
return TRUE;
if (!macrodef) {
ewprintf("Not defining kbd macro.");
return FALSE;
}
ewprintf("Keyboard macro defined");
macrodef = FALSE;
if (savemac.m_text)
free((char *) savemac.m_text);
if ((f & FFARG) == 0)
kbdmacro.m_count -= key.k_count;
else if (n != 1)
return runmacro(&kbdmacro, f, n - 1, FALSE);
return TRUE;
}
VOID
restore_macro()
{
if (kbdmacro.m_max > 0)
free((char *) kbdmacro.m_text);
kbdmacro = savemac;
}
/* ARGSUSED */
executemacro(f, n)
int f, n;
{
if (macrodef) {
ewprintf("Can't execute anonymous macro while defining one");
return FALSE;
}
if (kbdmacro.m_count == 0) {
ewprintf("No kbd macro has been defined");
return FALSE;
}
return runmacro(&kbdmacro, f, n, FALSE);
}
runmacro(run, f, count, onecommand)
struct macro *run;
int f, count, onecommand;
{
int status = TRUE;
struct macro *save;
if (run->m_count == 0)
return TRUE;
run->m_max = (f & FFARG) ? count : 1;
save = inmacro;
inmacro = run;
while (run->m_max != 0) {
run->m_cur = run->m_text;
while (run->m_cur - run->m_text < run->m_count) {
if ((status = doin()) != TRUE || onecommand) {
/* Error or abort */
run->m_max = 0;
break;
}
lastflag = thisflag;
thisflag = 0;
}
if (run->m_max > 0)
run->m_max -= 1;
}
inmacro = save;
return status != TRUE ? status
: (run->m_cur - run->m_text < run->m_count
? FALSE
: TRUE);
}
VOID
add_key_to_macro(c, mac)
KCHAR c;
struct macro *mac;
{
if (mac->m_count >= mac->m_max && growmacro(mac) != TRUE)
return;
mac->m_text[mac->m_count++] = c;
}
VOID
add_string_to_macro(string, mac)
char *string;
struct macro *mac;
{
int length;
if (!string)
return;
length = strlen(string);
while (length + mac->m_count >= mac->m_max)
if (growmacro(mac) != TRUE)
return;
while (*string)
mac->m_text[mac->m_count++] = *string++;
}
static int
growmacro(mac)
struct macro *mac;
{
KCHAR *oldtext;
int size;
oldtext = mac->m_text;
size = mac->m_max + MGROWSIZE;
if ((mac->m_text = (KCHAR *) malloc(size * sizeof(KCHAR))) == NULL) {
ewprintf("Can't get %d bytes", size * sizeof(KCHAR));
mac->m_text = oldtext;
return FALSE;
}
bcopy((char *) oldtext, (char *) mac->m_text,
mac->m_count * sizeof(KCHAR));
free((char *) oldtext);
mac->m_max = size;
return TRUE;
}
insertmacro(f, n)
int f, n;
{
register KCHAR *k;
register int i;
char macname[NMACN];
struct macro *out;
if (eread("Insert kbd macro (name): ", macname, NMACN, EFNEW | EFMACRO) != TRUE)
return FALSE;
if ((out = find_macro(macname)) == NULL) { /* shouldn't happen */
ewprintf("Macro %s not found!", macname);
return FALSE;
}
if (sinsert("fset ") == FALSE || sinsert(macname) == FALSE
|| sinsert(" \"") == FALSE)
return FALSE;
/* Insert all chars but the C-x ) used to end it */
for (k = out->m_text, i = out->m_count; i > 0; i -= 1, k += 1)
#ifdef FKEYS
if (*k >= KFIRST && *k <= KLAST) {
if (sinsert("\\f") == FALSE)
return FALSE ;
if (finsert((KCHAR) (*k - KFIRST)) == FALSE)
return FALSE ;
} else
#endif
if (*k < ' ') {
if (sinsert("\\^") == FALSE || linsert(1, CCHR(*k)) == FALSE)
return FALSE;
} else if (*k == '"') {
if (sinsert("\\\"") == FALSE)
return FALSE;
} else if (*k == '\\') {
if (sinsert("\\\\") == FALSE)
return FALSE;
} else if (*k > CCHR('?')) {
if (linsert(1, '\\') == FALSE || finsert(*k) == FALSE)
return FALSE;
} else if (linsert(1, *k) == FALSE)
return FALSE;
if (sinsert("\"\n") == FALSE)
return FALSE;
if (f & FFARG)
sinsert("; Need to put binding code here\n");
return TRUE;
}
macroset(f, n)
int f, n;
{
register int c, count;
struct macro *out;
char macname[NMACN];
KCHAR mactext[NXNAME];
if (!inmacro)
return FALSE; /* Only useable from eval-expression */
if (eread("", macname, NMACN, EFNEW) != TRUE)
return FALSE;
count = 0;
while ((c = getkey(SEESCR)) != SOFTCR) {
if (count >= NXNAME)
return FALSE;
mactext[count++] = c;
}
if ((out = makemacro(macname, mactext, count)) == NULL)
return FALSE;
return TRUE;
}
macroquery(f, n)
int f, n;
{
struct macro *save;
if (macrodef)
return TRUE;
if (!inmacro) {
ewprintf("Not defining or executing kbd macro");
return TRUE;
}
save = inmacro;
inmacro = NULL;
update();
for (;;) {
ewprintf("Proceed with macro? (Space, DEL or C-d)");
switch (getkey(FALSE)) {
case CCHR('G'):
return ABORT;
case CCHR('D'):/* Terminate all reps */
save->m_max = 1;
/* no more reps, so fall through to */
case CCHR('?'):/* Terminate this repition */
save->m_cur = &(save->m_text[save->m_count + 1]);
case ' ': /* Keep going as as is */
eerase();
inmacro = save;
return TRUE;
}
}
}
namemacro(f, n)
int f, n;
{
struct macro *out;
char macname[NMACN];
/* Get a valid name */
if (kbdmacro.m_count == 0) {
ewprintf("No keyboard macro defined");
return FALSE;
}
if (eread("Name for last kbd macro: ", macname, NMACN, EFNEW) != TRUE)
return FALSE;
if ((out = makemacro(macname, kbdmacro.m_text, kbdmacro.m_count)) == NULL)
return FALSE;
return TRUE;
}
static struct macro *
makemacro(name, text, count)
char *name;
KCHAR *text;
int count;
{
register struct macro *out;
char *ntmp;
KCHAR *ctmp;
/* Space for strings */
if ((ntmp = (char *) malloc(strlen(name) + 1)) == NULL) {
ewprintf("Can't get %d bytes", strlen(name) + 1);
return NULL;
}
if ((ctmp = (KCHAR *) malloc(count * sizeof(KCHAR))) == NULL) {
ewprintf("Can't get %d bytes", count * sizeof(KCHAR));
free(ntmp);
return NULL;
}
if (name_function(name) != NULL) {
ewprintf("Function %s is already defined and not a keyboard macro.",
name);
return NULL;
}
/* Get a macro to (re)use */
if ((out = find_macro(name)) != NULL) {
free(out->m_name);
free(out->m_text);
} else if ((out = (struct macro *) malloc(sizeof(struct macro))) == NULL) {
ewprintf("Can't get %d bytes", sizeof(struct macro));
free((char *) (ctmp));
free(ntmp);
return NULL;
} else { /* Add the new macro to the chain */
out->m_macp = kbdmacro.m_macp;
kbdmacro.m_macp = out;
}
/* Now, fill the silly bugger */
bcopy((char *) text, (char *) ctmp, count * sizeof(KCHAR));
strcpy(ntmp, name);
out->m_text = ctmp;
out->m_cur = NULL;
out->m_max = 0;
out->m_count = count;
out->m_name = ntmp;
return out;
}
struct macro *
find_macro(name)
char *name;
{
register struct macro *out;
if (!name)
return NULL;
out = kbdmacro.m_macp;
while (out) {
if (strcmp(out->m_name, name) == 0)
return out;
out = out->m_macp;
}
return NULL;
}
/*
* Insert a string into the current buffer. For insertmacro.
*/
sinsert(s)
register char *s;
{
while (*s) {
if (((*s == '\n') ? lnewline() : linsert(1, *s)) != TRUE)
return FALSE;
s += 1;
}
return TRUE;
}
/*
* insert a number into the current buffer. For insertmacro.
*/
static
finsert(k)
register KCHAR k;
{
if (k > 7 && finsert((KCHAR) (k >> 3)) == FALSE)
return FALSE;
return linsert(1, (k & 7) + '0');
}
#else
#include "nullfile.h"
#endif