home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Frozen Fish 1: Amiga
/
FrozenFish-Apr94.iso
/
bbs
/
alib
/
d3xx
/
d352
/
mg.lha
/
MG
/
src.LZH
/
mg
/
extend.c
< prev
next >
Wrap
C/C++ Source or Header
|
1990-05-23
|
7KB
|
320 lines
/*
* Extended commands (M-X) and startup file processing.
*/
#include "no_startup.h"
#include "no_macro.h"
#include "fkeys.h"
#include "do_eval.h"
#include "def.h"
#ifndef NO_MACRO
#include "macro.h"
#endif
#include "line.h"
#include "buffer.h"
#ifdef ANSI
#include <stdlib.h>
#include <string.h>
#endif
static char *skipwhite
PROTO((char *s, char *end));
static char *skiptowhite
PROTO((char *s, char *end));
static KCHAR backquote
PROTO((char **inp));
/*
* Extended command. Call the message line routine to read in the command
* name and apply autocompletion to it. When it comes back, look the name up
* in the symbol table and run the command if it is found. Print an error if
* there is anything wrong.
*/
extend(f, n)
{
int (*funct) PROTO((int, int));
#ifndef NO_MACRO
struct macro *m;
#endif
int s;
char xname[NXNAME];
if (!(f & FFARG))
s = eread("M-x ", xname, NXNAME, EFNEW | EFFUNC);
else
s = eread("%d M-x ", xname, NXNAME, EFNEW | EFFUNC, n);
if (s != TRUE)
return s;
if ((funct = name_function(xname)) != NULL)
return (*funct) (f, n);
#ifndef NO_MACRO
else if ((m = find_macro(xname)) != NULL)
return runmacro(m, f, n, FALSE);
#endif
ewprintf("[No match]");
return FALSE;
}
#ifdef DO_EVAL
/*
* Define the commands needed to do startup-file processing. This code is
* mostly a kludge just so we can get startup-file processing.
*
* We define eval-expression because it's easy. It can make *-set-key or
* define-key set an arbitrary key sequence, so it isn't useless.
*/
/*
* evalexpr - get one line from the user, and run it.
*/
/* ARGSUSED */
evalexpr(f, n)
{
int s;
char exbuf[NXNAME];
if ((s = ereply("Eval: ", exbuf, NXNAME)) != TRUE)
return s;
return excline(exbuf, strlen(exbuf));
}
/*
* evalbuffer - evaluate the current buffer as line commands. Useful for
* testing startup files.
*/
/* ARGSUSED */
evalbuffer(f, n)
{
register struct line *lp;
register struct buffer *bp = curbp;
register int s;
for (lp = lforw(bp->b_linep); lp != bp->b_linep; lp = lforw(lp)) {
if (llength(lp) >= NLINE)
return FALSE;
if ((s = excline(ltext(lp), llength(lp))) != TRUE)
return s;
}
return TRUE;
}
/*
* evalfile - go get a file and evaluate it as line commands. You can go get
* your own startup file if need be.
*/
/* ARGSUSED */
evalfile(f, n)
{
register int s;
char fname[NFILEN];
if ((s = ereply("Load file: ", fname, NFILEN)) != TRUE)
return s;
return load(fname);
}
/*
* load - go load the file name we got passed.
*/
load(fname)
char *fname;
{
int s = TRUE;
int nbytes;
char excbuf[128];
if ((fname = adjustname(fname)) == NULL)
return FALSE; /* just to be careful */
if (ffropen(fname) != FIOSUC)
return FALSE;
while ((s = ffgetline(excbuf, sizeof(excbuf) - 1, &nbytes)) == FIOSUC) {
if (excline(excbuf, nbytes) != TRUE) {
s = FIOERR;
ewprintf("Error loading file %s", fname);
break;
}
}
(VOID) ffclose();
if (s != FIOEOF || (nbytes && excline(excbuf, nbytes) != TRUE))
return FALSE;
return TRUE;
}
/*
* excline - run a line from a load file or eval-expression.
*/
excline(line, len)
char *line;
int len;
{
/* end points to where the terminating null should be */
char *funcp, *argp = NULL, *end, *inline;
struct macro *eval;
int status;
/* Make a copy we can scrawl on */
if (len == 0) return TRUE ;
if ((inline = malloc(len + 1)) == NULL) return FALSE ;
(VOID) bcopy(line, inline, len + 1);
line = inline ;
end = line + len; /* End of string marker */
funcp = skipwhite(line, end);
if (funcp >= end) {
free(inline) ;
return TRUE; /* No error on blank lines */
}
line = skiptowhite(funcp, end);
*line++ = '\0';
if (line < end) {
argp = skipwhite(line, end);
if (*argp != '-' && (*argp < '0' || '9' < *argp))
argp = NULL;
else {
line = skiptowhite(argp, end);
*line++ = '\0';
}
}
if ((eval = (struct macro *) malloc(sizeof(struct macro))) == NULL) {
free(inline) ;
return FALSE;
}
eval->m_count = eval->m_max = 0;
eval->m_text = eval->m_cur = NULL;
if (argp != NULL) {
add_key_to_macro(CCHR('U'), eval);
add_string_to_macro(argp, eval);
}
add_key_to_macro(METACH, eval);
add_key_to_macro('X', eval);
/* Pack in function */
add_string_to_macro(funcp, eval);
add_key_to_macro(SOFTCR, eval);
/* Pack away all the args now... */
while (line < end) {
argp = skipwhite(line, end);
if (argp >= end)
break;
if (*argp != '"') {
line = skiptowhite(argp, end);
*line++ = '\0';
add_string_to_macro(argp, eval);
} else { /* Quoted strings special again */
++argp;
while (*argp != '"' && argp < end) {
if (*argp != '\\')
add_key_to_macro((KCHAR) *argp++, eval);
else
add_key_to_macro(backquote(&argp), eval);
}
line = argp + 1;
}
add_key_to_macro(SOFTCR, eval);
}
status = runmacro(eval, FFOTHARG, 1, TRUE);
free((char *) eval->m_text);
free((char *) eval);
free(inline) ;
return status;
}
/*
* a pair of utility functions for the above
*/
static char *
skipwhite(s, end)
register char *s;
register char *end;
{
while (*s == ' ' || *s == '\t' && s < end)
s++;
if (*s == ';')
return end;
return s;
}
static char *
skiptowhite(s, end)
register char *s;
register char *end;
{
while (s < end && *s != ' ' && *s != '\t')
s++;
return s;
}
/*
* Put a backquoted string element into the keyboard macro. Return pointer to
* char following backquoted stuff.
*/
static KCHAR
backquote(inp)
char **inp;
{
register char *in;
register KCHAR c;
in = *inp;
in += 1; /* Skip over backquote */
c = *in++;
switch (ISUPPER(c) ? TOLOWER(c) : c) {
case 't':
c = CCHR('I');
break;
case 'n':
c = CCHR('J');
break;
case 'r':
c = CCHR('M');
break;
case '^':
c = *in++;
if (ISLOWER(c))
c = TOUPPER(c);
c = CCHR(c);
break;
case 'e':
c = METACH;
break;
#ifdef FKEYS
case 'f':
c = 0;
if (ISDIGIT(*in))
c += *in++ - '0';
if (ISDIGIT(*in))
c = (10 * c) + *in++ - '0';
if ((c += KFIRST) > KLAST)
c = KLAST;
break;
#endif
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
c = *in - '0';
if (in[1] <= '7' && in[1] >= '0') {
c <<= 3;
c += *++in - '0';
if (in[1] <= '7' && in[1] >= '0') {
c <<= 3;
c += *++in - '0';
}
}
break;
default:
c = CHARMASK(c);
break;
}
*inp = in; /* put the pointer back */
return c;
}
#endif