Article View: comp.sys.atari.st
Article #24780Uemail source (6 of 12)
From: RDROYA01
Date: Thu, 05 Feb 1987 11:42
Date: Thu, 05 Feb 1987 11:42
1455 lines
44967 bytes
44967 bytes
# This is a shell archive.
# Remove everything above and including the cut line.
# Then run the rest of the file through sh.
#----cut here-----cut here-----cut here-----cut here----#
#!/bin/sh
# shar: Shell Archiver
# Run the following text with /bin/sh to create:
# random.c
# misc.c
# macros.c
# This archive created: Tue Feb 3 17:52:51 1987
cat << \SHAR_EOF > random.c
/*
* This file contains the
* command processing functions for
* a number of random commands. There is
* no functional grouping here, for
* sure.
*/
#include <stdio.h>
#include "ed.h"
int tabsize; /* Tab size (0: use real tabs) */
char fillprefix[80]; /* rather large but who knows */
int yankcflag = FALSE;
/*
* Set fill column to n. The fill column is global, but the individual
* buffer can be filled or not depending on its mode.
*/
setfillcol(f, n)
register int f, n;
{
register WINDOW *wp;
register BUFFER *bp;
fillcol = (n == 1) ? (getccol(FALSE) + 1) : n;
n = fillcol;
wp = wheadp;
bp = curwp->w_bufp;
if (n > 1)
{
bp->b_bmode |= BMWRAP;
bp->b_bmode &= ~BMNWRAP;
}
else
{
bp->b_bmode |= BMNWRAP;
bp->b_bmode &= ~BMWRAP;
}
upmode();
mlwrite("Fill column is %d", n);
return(TRUE);
}
/*
* Set indent column to n or set fill prefix to string.
*/
setindcol(f, n)
register int f, n;
{
short curdo; /* current dot offset */
register short tdo; /* moveable dot offset */
register short i;
char tstring[80]; /* temporary store for prefix string */
i = 0;
tdo = 0;
curdo = curwp->w_doto;
if (n>1) /* called with argument, so just set the indcol */
{
if (n >= 80)
n=79;
indcol = n;
/* copy the correct number of tabs and spaces into string */
if ((tdo=indcol/8)!=0)
while (tdo--)
tstring[i++] = '\t';
if ((tdo=indcol%8)!=0)
while (tdo--)
tstring[i++] = ' ';
tstring[i] = '\0';
strncpy(fillprefix,tstring,79);
mlwrite("Indent column is %d", indcol);
return(TRUE);
}
indcol = getccol(FALSE) +1;
/* now fabricate fill prefix string */
do {
curwp->w_doto = tdo;
tstring[tdo] = lgetc(curwp->w_dotp,tdo);
} while (++tdo < curdo && tdo < 80);
tstring[curdo] = '\0';
curwp->w_doto = curdo;
strncpy(fillprefix,tstring,79);
mlwrite("Fill prefix is '%s'",fillprefix);
return(TRUE);
}
/*
* Display the current position of the cursor,
* in origin 1 X-Y coordinates, the character that is
* under the cursor (in hex), and the fraction of the
* text that is before the cursor. The displayed column
* is not the current column, but the column that would
* be used on an infinite width display. Normally this
* is bound to "C-X =".
*/
showcpos(f,n)
int f, n;
{
register LINE *clp;
register long nch;
register long nbc;
register long nmc;
register int cbo;
register int cac;
register int page;
register int col;
register int i;
register int row;
register long tl1;
float ratio, tf1, tf2;
char buf[12], *ftoa();
i = 0;
clp = lforw(curbp->b_linep); /* Grovel the data. */
cbo = 0;
nch = 0;
for (;;) {
if (clp==curwp->w_markp && cbo==curwp->w_marko)
nmc = nch;
if (clp==curwp->w_dotp && cbo==curwp->w_doto) {
nbc = nch;
row = i;
if (cbo == llength(clp))
cac = '\n';
else
cac = lgetc(clp, cbo);
}
if (cbo == llength(clp)) {
if (clp == curbp->b_linep)
break;
clp = lforw(clp);
++i;
cbo = 0;
} else
++cbo;
++nch;
}
col = getccol(FALSE) + 1; /* Get real column. */
if (nch != 0L)
{
tl1 = nbc * 100L;
tf1 = (float)tl1;
tf2 = (float)nch;
ratio = tf1/tf2;
}
(void)ftoa(ratio,buf,4);
buf[strlen(buf)-2] = '\0'; /* fool precision error */
if (curwp->w_dotp == curbp->b_linep)
row = i;
page = row / pagelen + 1;
mlwrite("page:=%d col:=%d line:=%d CH:=0x%x mark:=%D point:=%D (%s%% of %D)",
page, col, row, cac, nmc, nbc, buf, nch);
return (TRUE);
}
/*
* Return current column. Stop at first non-blank given TRUE argument.
*/
getccol(bflg)
int bflg;
{
register int c, i, col;
col = 0;
for (i=0; i<curwp->w_doto; ++i) {
c = lgetc(curwp->w_dotp, i);
if (c!=' ' && c!='\t' && bflg)
break;
if (c == '\t')
col |= 0x07;
else if (c<0x20 || c==0x7F)
++col;
++col;
}
return(col);
}
/*
* Twiddle the two characters on either side of
* dot. If dot is at the end of the line twiddle the
* two characters before it. Return with an error if dot
* is at the beginning of line; it seems to be a bit
* pointless to make this work. This fixes up a very
* common typo with a single stroke. Normally bound
* to "C-T". This always works within a line, so
* "WFEDIT" is good enough.
*/
twiddle(f, n)
register int f, n;
{
register LINE *dotp;
register int doto;
register int cl;
register int cr;
dotp = curwp->w_dotp;
doto = curwp->w_doto;
if (doto==llength(dotp) && --doto<0)
return (FALSE);
cr = lgetc(dotp, doto);
if (--doto < 0)
return (FALSE);
cl = lgetc(dotp, doto);
lputc(dotp, doto+0, cr);
lputc(dotp, doto+1, cl);
lchange(WFEDIT);
return (TRUE);
}
/*
* Quote the next character, and
* insert it into the buffer. All the characters
* are taken literally, with the exception of the newline,
* which always has its line splitting meaning. The character
* is always read, even if it is inserted 0 times, for
* regularity. Bound to "M-Q" (for me) and "C-Q" (for Rich,
* and only on terminals that don't need XON-XOFF).
*/
quote(f, n)
register int f, n;
{
register int s;
register int c;
c = (*term.t_getchar)();
if (n < 0)
return (FALSE);
if (n == 0)
return (TRUE);
if (c == '\n') {
do {
s = lnewline();
} while (s==TRUE && --n);
return (s);
}
return (linsert(n, c));
}
/*
* Set tab size if given non-default argument (n <> 1). Otherwise, insert a
* tab into file. If given argument, n, of zero, change to true tabs.
* If n > 1, simulate tab stop every n-characters using spaces.
* This has to be done in this slightly funny way because the
* tab (in ASCII) has been turned into "C-I" (in 10
* bit code) already. Bound to "C-I".
*/
tab(f, n)
register int f, n;
{
if (n < 0)
return (FALSE);
if (n == 0 || n > 1) {
tabsize = n;
return(TRUE);
}
if (! tabsize)
return(linsert(1, '\t'));
return(linsert(tabsize - (getccol(FALSE) % tabsize), ' '));
}
/*
* Open up some blank space. The basic plan
* is to insert a bunch of newlines, and then back
* up over them. Everything is done by the subcommand
* processors. They even handle the looping. Normally
* this is bound to "C-O".
*/
openline(f, n)
register int f, n;
{
register int i;
register int s;
if (n < 0)
return (FALSE);
if (n == 0)
return (TRUE);
i = n; /* Insert newlines. */
do {
s = lnewline();
} while (s==TRUE && --i);
if (s == TRUE) /* Then back up overtop */
s = backchar(f, n); /* of them all. */
return (s);
}
/*
* Insert a newline. Bound to "C-M".
* If you are at the end of the line and the
* next line is a blank line, just move into the
* blank line. This makes "C-O" and "C-X C-O" work
* nicely, and reduces the ammount of screen
* update that has to be done. This would not be
* as critical if screen update were a lot
* more efficient.
*/
newline(f, n)
register int f, n;
{
register LINE *lp;
register int s;
extern unsigned char insflag;
if (n < 0)
return (FALSE);
if (yankcflag == TRUE || insflag == TRUE)
goto around;
if (n == 1 && (curbp->b_bmode&BMCMODE) != 0
&& curwp->w_dotp != curbp->b_linep)
return(indent(TRUE,n));
if (indcol > 0)
return(indent(MAYBE,1));
around: while (n--) {
lp = curwp->w_dotp;
if (llength(lp) == curwp->w_doto
&& lp != curbp->b_linep
&& llength(lforw(lp)) == 0) {
if ((s=forwchar(FALSE, 1)) != TRUE)
return (s);
} else if ((s=lnewline()) != TRUE)
return (s);
}
return (TRUE);
}
/*
* Delete blank lines around dot.
* What this command does depends if dot is
* sitting on a blank line. If dot is sitting on a
* blank line, this command deletes all the blank lines
* above and below the current line. If it is sitting
* on a non blank line then it deletes all of the
* blank lines after the line. Normally this command
* is bound to "C-X C-O". Any argument is ignored.
*/
deblank(f, n)
register int f, n;
{
register LINE *lp1;
register LINE *lp2;
register int nld;
lp1 = curwp->w_dotp;
while (llength(lp1)==0 && (lp2=lback(lp1))!=curbp->b_linep)
lp1 = lp2;
lp2 = lp1;
nld = 0;
while ((lp2=lforw(lp2))!=curbp->b_linep && llength(lp2)==0)
++nld;
if (nld == 0)
return (TRUE);
curwp->w_dotp = lforw(lp1);
curwp->w_doto = 0;
return (ldelete(nld));
}
/*
* Insert a newline, then enough
* tabs and spaces to duplicate the indentation
* of the previous line. Assumes tabs are every eight
* characters. Quite simple. Figure out the indentation
* of the current line. Insert a newline by calling
* the standard routine. Insert the indentation by
* inserting the right number of tabs and spaces.
* Return TRUE if all ok. Return FALSE if one
* of the subcomands failed. Normally bound
* to "C-J".
*/
indent(f, n)
register int f, n;
{
register int nicol;
register int c;
register int i;
if (n < 0)
return (FALSE);
if (f == MAYBE) /* This call is to fill a paragraph or wrap an */
{ /* indented line */
if (lnewline() == FALSE || putlin(fillprefix) == FALSE)
return(FALSE);
return(TRUE);
}
while (n--) {
nicol = 0;
for (i=0; i<llength(curwp->w_dotp); ++i) {
c = lgetc(curwp->w_dotp, i);
if (c!=' ' && c!='\t')
break;
if (c == '\t')
nicol |= 0x07;
++nicol;
}
if (lnewline() == FALSE
|| ((i=nicol/8)!=0 && linsert(i, '\t')==FALSE)
|| ((i=nicol%8)!=0 && linsert(i, ' ')==FALSE))
return (FALSE);
}
return (TRUE);
}
/* MDROPLN : META command to drop the current line and indent the same
* as the current line. Bound to M-O.
*/
mdropln(f, n)
register int f, n;
{
register int nicol;
register int c;
register int i;
if (n < 0)
return (FALSE);
curwp->w_doto = 0;
while (n--) {
nicol = 0;
for (i=0; i<llength(curwp->w_dotp); ++i) {
c = lgetc(curwp->w_dotp, i);
if (c!=' ' && c!='\t')
break;
if (c == '\t')
nicol |= 0x07;
++nicol;
}
if (openline(NULL, 1) == FALSE
|| ((i=nicol/8)!=0 && linsert(i, '\t')==FALSE)
|| ((i=nicol%8)!=0 && linsert(i, ' ')==FALSE))
return (FALSE);
}
return (TRUE);
}
/*
* Delete forward. This is real
* easy, because the basic delete routine does
* all of the work. Watches for negative arguments,
* and does the right thing. If any argument is
* present, it kills rather than deletes, to prevent
* loss of text if typed with a big argument.
* Normally bound to "C-D".
*/
forwdel(f, n)
register int f, n;
{
if (n < 0)
return (backdel(f, -n));
if (f != FALSE) { /* Really a kill. */
if ((lastflag&CFKILL) == 0)
kdelete();
thisflag |= CFKILL;
}
return (ldelete(n, f));
}
/*
* Delete backwards. This is quite easy too,
* because it's all done with other functions. Just
* move the cursor back, and delete forwards.
* Like delete forward, this actually does a kill
* if presented with an argument. Bound to both
* "RUBOUT" and "C-H".
*/
backdel(f, n)
register int f, n;
{
register int s;
if (n < 0)
return (forwdel(f, -n));
if (f != FALSE) { /* Really a kill. */
if ((lastflag&CFKILL) == 0)
kdelete();
thisflag |= CFKILL;
}
if ((s=backchar(f, n)) == TRUE)
s = ldelete(n, f);
return (s);
}
/*
* Kill text. If called without an argument,
* it kills from dot to the end of the line, unless it
* is at the end of the line, when it kills the newline.
* If called with an argument of 0, it kills from the
* start of the line to dot. If called with a positive
* argument, it kills from dot forward over that number
* of newlines. If called with a negative argument it
* kills backwards that number of newlines. Normally
* bound to "C-K".
*/
kill(f, n)
register int f, n;
{
register int chunk;
register LINE *nextp;
if ((lastflag&CFKILL) == 0) /* Clear kill buffer if */
kdelete(); /* last wasn't a kill. */
thisflag |= CFKILL;
if (f == FALSE) {
chunk = llength(curwp->w_dotp)-curwp->w_doto;
if (chunk == 0)
chunk = 1;
} else if (n == 0) {
chunk = curwp->w_doto;
curwp->w_doto = 0;
} else if (n > 0) {
chunk = llength(curwp->w_dotp)-curwp->w_doto+1;
nextp = lforw(curwp->w_dotp);
while (--n) {
if (nextp == curbp->b_linep)
return (FALSE);
chunk += llength(nextp)+1;
nextp = lforw(nextp);
}
} else {
mlwrite("neg kill");
return (FALSE);
}
return (ldelete(chunk, TRUE));
}
/*
* Yank text back from the kill buffer. This
* is really easy. All of the work is done by the
* standard insert routines. All you do is run the loop,
* and check for errors. Bound to "C-Y". The blank
* lines are inserted with a call to "newline"
* instead of a call to "lnewline" so that the magic
* stuff that happens when you type a carriage
* return also happens when a carriage return is
* yanked back from the kill buffer.
*/
yank(f, n)
register int f, n;
{
register int c;
register int i;
extern int kused;
if (n < 0)
return (FALSE);
if (curbp->b_bmode&BMCMODE)
yankcflag = TRUE; /* don't reindent yanked text */
while (n--) {
i = 0;
while ((c=kremove(i)) >= 0) {
if (c == '\n') {
if (newline(FALSE, 1) == FALSE)
return (FALSE);
} else {
if (linsert(1, c) == FALSE)
return (FALSE);
}
++i;
}
}
yankcflag = FALSE;
return (TRUE);
}
SHAR_EOF
cat << \SHAR_EOF > misc.c
/* misc.c miscellaneous commands, some macros and mode commands */
#include <stdio.h>
#include <ctype.h>
#include <osbind.h>
#include "ed.h"
typedef short boolean;
static int count = 1;
char *modes[] = {"Fundamental","Wrap","C"};
/* MINDNL : META command Indent subsequent newline same as the present
* one. Bound to M-J.
*/
mindnl(f, n)
register int f, n;
{
curwp->w_doto = llength(curwp->w_dotp);
return(indent(f, n));
}
/* MDELELN : CTRL command Delete entire line from beginning. Bound to ^K.
*/
mdeleln(f, n)
register int f, n;
{
curwp->w_doto = 0;
return(kill(NULL, 1));
}
/* MDELWLN : META command Delete entire line including NL. Bound to M-^K.
*/
mdelwln(f, n)
register int f, n;
{
curwp->w_doto = 0;
return(kill(TRUE, 1));
}
/* MDELIND : META command Delete beginning indentation on line. Bound to M-\.
*/
mdelind(f, n)
register f, n;
{
register int odo;
f = llength(curwp->w_dotp);
odo = curwp->w_doto;
curwp->w_doto = 0;
while ((n = lgetc(curwp->w_dotp, curwp->w_doto)) <= ' '
&& curwp->w_doto != llength(curwp->w_dotp))
if (forwdel(NULL, 1) == FALSE)
return(FALSE);
if ((n = llength(curwp->w_dotp)) == NULL)
curwp->w_doto = n;
else {
if (odo == NULL)
curwp->w_doto = odo;
else
curwp->w_doto = odo - (f - n);
}
lchange(WFEDIT);
return(TRUE);
}
/* CLOWSP Meta Command Close up white space from point forward.
* Bound to M-^O.
*/
clowsp(f, n)
register int f, n;
{
while ((n = lgetc(curwp->w_dotp, curwp->w_doto)) <= ' '
|| curwp->w_doto == llength(curwp->w_dotp))
if(forwdel(NULL, 1) == FALSE)
return(FALSE);
return(linsert(1, ' '));
}
/* MARKPAR : Meta Command Mark paragraph for moving or deleting. Bound to
* M-H.
*/
markpar(f, n)
register int f, n;
{
goteop(NULL, n);
setmark(NULL, 1);
gotbop(NULL, n);
return(TRUE);
}
/* KILLSENT : Meta command Kills sentence forward. Bound to M-K.
*/
killsent(f, n)
register int f, n;
{
setmark(NULL,1);
forwsent(f, n);
return(killregion(NULL, 1));
}
/* TGLCASE : Meta command Toggles case of letter at point. Bound to M-^P.
*/
tglcase(f, n)
register int f, n;
{
register int c;
if (n < 0)
return(FALSE);
while(n--)
{
c = lgetc(curwp->w_dotp, curwp->w_doto);
if(islower(c))
c = toupper(c);
else
c = tolower(c);
lputc(curwp->w_dotp, curwp->w_doto, c);
lchange(WFEDIT);
if(forwchar(FALSE, 1) == FALSE)
return(FALSE);
}
return(TRUE);
}
/* GRTW eXtended command Globally removes trailing white space. Bound to
* ^X-\.
*/
grtw(f, n)
register int f, n;
{
register int dlo, d;
register LINE *dlp;
dlp = curwp->w_dotp;
dlo = curwp->w_doto;
gotobob(NULL, 1);
while((d = ltrw(FALSE, 1)) != EOF)
forwline(NULL, 1);
if (dlo > llength(dlp))
dlo = llength(dlp);
curwp->w_dotp = dlp;
curwp->w_doto = dlo;
curwp->w_flag |= WFHARD;
return(TRUE);
}
/* LTRW internal function delete trailing white space on current line.
* called by grtw() and fillpar(). Any arguments are ignored. Returns
* length of line or EOF at end of buffer.
*/
ltrw(f, n)
register int f, n;
{
register int c, d;
if(curwp->w_dotp == curbp->b_linep)
return(EOF);
d = llength(curwp->w_dotp);
curwp->w_doto = d;
if (d == NULL)
return(NULL);
while (--d >= 0)
{
backchar(FALSE, 1);
c = lgetc(curwp->w_dotp, curwp->w_doto);
if(c != ' ' && c != '\t')
break;
if(ldelete(1, NULL) == FALSE)
return(EOF);
}
return(llength(curwp->w_dotp));
}
/* TWADDLE Meta command More at twiddle. Transpose two words on a line.
* Bound to M-T.
*/
twaddle(f, n)
register int f, n;
{
boolean flag = FALSE;
boolean punct= FALSE;
register int c;
char word[20];
n = 0;
if(backchar(FALSE, 1) == FALSE)
return (FALSE);
c = lgetc(curwp->w_dotp, curwp->w_doto);
if(ispunct(c))
{
punct = c;
if (forwdel(NULL, 1) == FALSE)
return (FALSE);
}
else if (forwchar(FALSE, 1) == FALSE)
return (FALSE);
c = lgetc(curwp->w_dotp, curwp->w_doto);
if (isspace(c))
flag = c;
else if (ispunct(c))
flag = c;
else
word[n++] = c;
if (ldelete(1, NULL) == FALSE)
return (FALSE);
while(c = lgetc(curwp->w_dotp, curwp->w_doto))
{
if (curwp->w_doto == llength(curwp->w_dotp))
break;
if (isalnum(c))
{
word[n++] = c;
if (forwdel(NULL, 1) == FALSE)
return (FALSE);
}
else
break;
}
if(backword(NULL, 1) == FALSE)
return (FALSE);
c = 0;
while(n--)
if (linsert(1, word[c++]) == FALSE)
return (FALSE);
if (punct)
if (linsert(1, punct) == FALSE)
return (FALSE);
if (flag)
if (linsert(1, flag) == FALSE)
return (FALSE);
return(TRUE);
}
/* MRFLUSH META Command right flush current line. Bound to M-^R */
mrflush(f, n)
register int f, n;
{
register short p; /* where we are in line */
register short l; /* length of line */
register short o; /* offset for new location */
p = curwp->w_doto;
if((l = llength(curwp->w_dotp)) == NULL)
return(FALSE);
if (fillcol)
f = fillcol;
else f = 80;
if((o = f - l) < 0)
return(FALSE);
curwp->w_doto = 0;
linsert(o, ' ');
forwchar(NULL, p);
return(TRUE);
}
/* MCENTER META Command center current line. Bound to M-^C */
mcenter(f, n)
register int f, n;
{
register short p; /* where we are in line */
register short l; /* length of line */
register short o; /* offset for new location */
p = curwp->w_doto;
if((l = llength(curwp->w_dotp)) == NULL)
return(FALSE);
if (fillcol)
f = fillcol;
else f = 80;
if((o = (f - l)/2) < 0)
return(FALSE);
curwp->w_doto = 0;
linsert(o, ' ');
forwchar(NULL, p);
return(TRUE);
}
/* SETMODE Extended Command. Only one mode at a time. Bound to ^X-M.
*/
setmode(f, n)
register int f, n;
{
char mymode[12];
register char *ptr;
extern char *index();
register BUFFER *bp;
register WINDOW *wp;
if((f=mlreply("New mode: ",mymode,12)) != TRUE)
return(f);
/* don't fail because of stray spaces */
if ((ptr=index(mymode,' '))!=NULL)
*ptr = '\0';
else if ((ptr=index(mymode,'\t'))!=NULL)
*ptr = '\0';
n = strlen(mymode);
/* adjust case */
for (f=0;f<=n;f++)
if (f == 0)
mymode[f] = toupper(mymode[f]);
else
mymode[f] = tolower(mymode[f]);
for (f=0;f<=NUMMODES-1;f++)
{
if (strncmp(modes[f],mymode,12)==0)
{
switch(f)
{
case 0:
curbp->b_bmode &= ~BMWRAP;
curbp->b_bmode &= ~BMCMODE;
curbp->b_bmode |= BMNWRAP;
break;
case 1:
curbp->b_bmode &= ~BMNWRAP;
curbp->b_bmode &= ~BMCMODE;
curbp->b_bmode |= BMWRAP;
break;
case 2:
curbp->b_bmode &= ~BMNWRAP;
curbp->b_bmode &= ~BMWRAP;
curbp->b_bmode |= BMCMODE;
break;
}
upmode();
return(TRUE);
}
}
mlwrite("No match");
return(FALSE);
}
/* SGLMODE META-Command Set the flag glmode. The flag is used only by
* bfind and this command. Call this after reading in a new color file
* and answer "color" to the mode question to install new colors.
*/
sglmode(f, n)
int f, n;
{
char mymode[12];
register char *ptr;
extern char *index();
register BUFFER *bp;
register WINDOW *wp;
if((f=mlreply("New global mode: ",mymode,12)) != TRUE)
return(f);
/* don't fail because of stray spaces */
if ((ptr=index(mymode,' '))!=NULL)
*ptr = '\0';
else if ((ptr=index(mymode,'\t'))!=NULL)
*ptr = '\0';
n = strlen(mymode);
/* adjust case */
for (f=0;f<=n;f++)
if (f == 0)
mymode[f] = toupper(mymode[f]);
else
mymode[f] = tolower(mymode[f]);
if (strcmp(mymode,"Color")==NULL)
{
ttopen();
return(TRUE);
}
for (f=0;f<=NUMMODES-1;f++)
{
if (strncmp(modes[f],mymode,12)==0)
{
switch(f)
{
case 0:
glmode &= ~BMWRAP;
glmode &= ~BMCMODE;
glmode |= BMNWRAP;
break;
case 1:
glmode &= ~BMNWRAP;
glmode &= ~BMCMODE;
glmode |= BMWRAP;
break;
case 2:
glmode &= ~BMNWRAP;
glmode &= ~BMWRAP;
glmode |= BMCMODE;
break;
}
return(TRUE);
}
}
mlwrite("No match");
return(FALSE);
}
/* RETTPA META-Command returns current memory use and available buffer
* to msgline. Bound to M-@.
*/
rettpa(f, n)
int f, n;
#if ST
{
register long low, u_buf;
unsigned long tpa, stkadd;
extern long progend;
extern unsigned long getmem();
extern long sbrk();
low = sbrk(0);
stkadd = getmem();
u_buf = low - progend;
tpa = stkadd - low;
mlwrite("Used:%D bytes Heap address:%D Stack address:%lu TPA:%lu bytes",
u_buf,low,stkadd,tpa);
return(TRUE);
}
#else
{
return(FALSE);
}
#endif
/* GOLINE Meta command go to argument line in text. Bound to M-G.
*/
goline(f, n)
register int f, n;
{
return(gotobob(f, n) && forwline(f, n));
}
/* ENUMERATE Meta Command Based on value of n, initialize or increment
* a counter variable. If n < NULL, simply write the value on the mode
* line. Bound to M-CTRL-N.
*/
enumerate(f, n)
register int f, n;
{
char num[5+1];
if (n == -1) /* request value of count */
mlwrite("Counter = %d",count);
else if (n == TRUE) /* increment counter */
count++;
else if (n == NULL)
{
ltoa(num, 5, (long)count++); /* make it a string */
putlin(num); /* put count in doc */
putlin(". "); /* do some formatting */
}
else if (n > 1) /* n > 1. Set counter to arg value */
{
count = n;
enumerate(NULL,-1);
}
else if (n < -1) /* Request to reset counter */
count = 1;
return(TRUE);
}
/* GOSPELL eXtended command goto next spell mark to correct spelling
* mistakes. Bound to X-S.
*/
gospell(f, n)
register int f, n;
{
while(TRUE)
{
if (curwp->w_dotp == curbp->b_linep)
{
mlwrite("No spell marks found");
return(FALSE);
}
f = lgetc(curwp->w_dotp, curwp->w_doto);
if (f == 0x93)
{
if (forwdel(NULL, TRUE) == FALSE)
return (FALSE);
mlwrite("Correction mark found");
return(TRUE);
}
forwchar(NULL,TRUE);
}
}
/* showtime print current time on mode line. If n > 1 insert in document.
*/
showtime(f,n)
register int f, n;
{
register int time;
register int hours, minutes, seconds;
char mortem[3]; /* am or pm */
char timeline[20];
time = Tgettime();
seconds = (time&31)*2;
minutes = (time>>5)&63;
hours = (time>>11)&31;
if (hours >= 12)
strcpy(mortem, "pm");
else
strcpy(mortem, "am");
if (hours > 12)
hours-=12;
if (hours == 0)
hours = 12;
sprintf(timeline,"Time: %d:%02d:%02d %s",hours,minutes,seconds,mortem);
if (n <= 1)
mlwrite(timeline);
else if (n == HUGE)
mtwrite(timeline);
else
putlin(timeline);
return(TRUE);
}
/* MDONCOM do named command. Bound to M-X.
*/
mdoncom(f, n)
register int f, n;
{
char fname[16]; /* function name */
register char *ptr;
extern char *index();
extern short getktpcode();
register short c;
mlreply("Function: ",fname,15);
/* don't fail because of stray spaces */
if ((ptr=index(fname,' '))!=NULL)
*ptr = '\0';
else if ((ptr=index(fname,'\t'))!=NULL)
*ptr = '\0';
if ((c=getktpcode(fname))!=NULL)
c = (short)execute(c,f,n);
else
{
mlwrite("No match!");
(*term.t_beep)();
}
return((int)c);
}
SHAR_EOF
cat << \SHAR_EOF > macros.c
/* macros.c routines to bind keyboard macros to individual keys */
#include <stdio.h>
#include "ed.h"
#define FLEN 14
static FILE *mp; /* file pointer for LOAD and SAVE */
static char macfile[NFILEN+1] = "uemail.mcr";
static short macstr[NKBDM];
typedef struct MACTAB {
struct MACTAB *m_fmac; /* next MACTAB */
short *keymac; /* pointer to the macro */
char key; /* the key */
} MACTAB;
MACTAB *mheadp = NULL; /* pointer to header structure */
/* GETMACRO eXtended command to store a macro in the table above.
* Copies the current keyboard macro to the appropriate array.
* Bound to ^X-`.
*/
getmacro(f, n)
int f,n;
{
register int c,i;
short *maccpy();
register MACTAB *mt;
MACTAB *mcralloc();
/* is there currently a macro being defined ? */
if (kbdmip != NULL || kbdmop != NULL) {
mlwrite("Not now");
return (FALSE);
}
mlwrite("Key to bind to current macro: ");
c = ttgetc();
ttputc(c);
if((mt=mcralloc(TRUE,c))==NULL)
return(FALSE);
i = maclen(kbdm);
mt->key = c; /* install the key */
if ((mt->keymac=(short *)malloc((i+1)*sizeof(short)))==NULL)
{
mlwrite("Cannot allocate space for macro");
return(FALSE);
}
maccpy(mt->keymac,kbdm); /* copy the macro */
return(TRUE);
}
/* PUTMACRO AGRAVE command finds macro associated with key returned
* by ttgetc and executes the macro.
*/
putmacro(f, n)
register int f, n;
{
register int c;
short *maccpy();
register MACTAB *mt;
MACTAB *mcralloc();
c = ttgetc(); /* get next char */
switch(c)
{
case 0x07: /* abort */
return(ctrlg(FALSE,0));
case 0x0c: /* load a macro file */
return(loadmac(TRUE));
case 0x0d: /* "make" a macro file */
return(savemac());
case 0x12: /* incremental search back */
return(backisearch(f, n));
case 0x13: /* incremental search forward */
return(forwisearch(f, n));
case 0x14: /* get time */
return(showtime(f,n));
case '`':
return(linsert(1,c));
}
if (kbdmip!=NULL || kbdmop!=NULL)
{
mlwrite("Not now");
return (FALSE);
}
/* actually, there should be no way mheadp could != NULL and
* its forward pointer == NULL, but it's best to check
*/
if (mheadp==NULL || mheadp->m_fmac == NULL)
{
mlwrite("No defineable macros assigned");
return(FALSE);
}
if((mt=mcralloc(FALSE,c))!= (MACTAB *)NULL)
{
/* save current macro to restore later */
maccpy(macstr,kbdm);
maccpy(kbdm,mt->keymac);
c=ctlxe(f, n); /* execute mac in keybrd.c */
maccpy(kbdm,macstr);
return(c);
}
(*term.t_beep)();
return(FALSE);
}
/* LOADMAC load a macro file and install the macros into memory.
* Bound to `^L.
*/
loadmac(f)
int f;
{
short *maccpy();
register int c,i;
register short s;
register MACTAB *mt;
MACTAB *mcralloc();
if (f==TRUE) /* FALSE == Called from main */
{
if(readpattern("Load macros: ",macfile)==ABORT)
return(ABORT);
}
else
strcpy(macfile,"uemail.mcr");
if (macfile[0] == '~')
parsefn(macfile);
if ((mp=fopen(macfile,"r"))==NULL)
{
mlwrite("Cannot open %s",macfile);
return(FALSE);
}
if ((s=getw(mp))!=(CTLX|'('))
{
mlwrite("Macro file format error: %s",macfile);
fclose(mp);
return(FALSE);
}
while((c=fgetc(mp))!=EOF)
{
i=0;
mlwrite("[Installing macro for key %c]",c);
if((mt=mcralloc(TRUE,c))==NULL)
{
fclose(mp);
return(FALSE);
}
while ((s=getw(mp))!=(CTLX|')'))
{
if (feof(mp))
{
mlwrite("Read error on: %s",macfile);
break;
}
macstr[i++]=s;
}
macstr[i] = CTLX|')';
mt->key = c; /* install the key */
if ((mt->keymac=(short *)malloc((i+1)*sizeof(short)))==NULL)
{
fclose(mp);
mlwrite("Cannot allocate space for macro");
return(FALSE);
}
maccpy(mt->keymac,macstr); /* copy the macro */
}
fclose(mp);
return(TRUE);
}
/* SAVEMAC function to save current keyboard macros to a file.
* Bound to `^M (makemac).
*/
savemac()
{
short *maccpy();
register int i;
register short s;
register MACTAB *mt;
if(readpattern("Save macros: ",macfile)==ABORT)
return(ABORT);
if (macfile[0] == '~')
parsefn(macfile);
if ((mp=fopen(macfile,"w"))==NULL)
{
mlwrite("Cannot open %s",macfile);
return(FALSE);
}
/* actually, there should be no way mheadp could != NULL and
* its forward pointer == NULL, but it's best to check
*/
if (mheadp==NULL || mheadp->m_fmac == NULL)
{
mlwrite("No defineable macros assigned");
return(FALSE);
}
/* don't change the file format or the load function
* will fail
*/
mt=mheadp->m_fmac;
putw(CTLX|'(',mp);
while(mt != NULL)
{
i=0;
mlwrite("[Saving key: %c]",mt->key);
maccpy(macstr,mt->keymac);
fputc(mt->key,mp);
while(macstr[i]!=(CTLX|')'))
putw(macstr[i++],mp);
putw(CTLX|')',mp);
mt=mt->m_fmac; /* next pointer */
}
fclose(mp);
return(TRUE);
}
/* find an existing keyboard macro or get space for a new one. Return
* a pointer to the MACTAB structure so others can do with it what they
* will.
*/
MACTAB *
mcralloc(f,c)
register int f,c;
{
register MACTAB *mt;
if (mheadp == NULL)
{
if ((mheadp=(MACTAB *)malloc(sizeof(MACTAB))) == NULL)
{
mlwrite("Cannot allocate %d bytes",sizeof(MACTAB));
return(FALSE);
}
mheadp->m_fmac = (MACTAB *)NULL;
}
/* check to see if this one has already been allocated */
mt=mheadp;
while(mt->m_fmac != (MACTAB *)NULL)
{
if (mt->m_fmac->key == c)
{
if (f == TRUE) /* reallocate old */
free(mt->m_fmac->keymac);
return(mt->m_fmac);
}
mt=mt->m_fmac; /* next pointer */
}
/* this was a get request. return if no macro found */
if (f==FALSE)
return(FALSE);
/* otherwise must be a new request */
if ((mt->m_fmac=(MACTAB *)malloc(sizeof(MACTAB)))==NULL)
{
mlwrite("Cannot allocate %d bytes",sizeof(MACTAB));
return(FALSE);
}
mt->m_fmac->m_fmac = (MACTAB *)NULL; /* new pointer */
return(mt->m_fmac);
}
/* PUTLIN function to service putmacro() also used by enumerate and showtime */
putlin(lin)
register char *lin;
{
while(*lin)
linsert(1,*lin++);
}
/* get actual length of macro to allocate spacr */
maclen(mac)
register short *mac;
{
register int i;
i = 1;
while(*mac++ != (CTLX|')'))
++i;
return(i);
}
/* similar to strcpy but copies one keyboard macro to another returning
* the address of the destination string.
*/
short *
maccpy(dest, sour)
register short *dest;
register short *sour;
{
register short *dptr;
register short s;
dptr = dest;
while ((s = *sour++) != (CTLX|')'))
*dest++ = s;
*dest = CTLX|')';
return(dptr);
}
SHAR_EOF
# End of shell archive
exit 0
%NONAME-W-NOMSG, Message number 00000000
Technical Details
Message-ID:
<8702052237.AA16224@ucbvax.Berkeley.EDU>Path:
arc1-ca.pugleaf.net!utzoo!watmath!clyde!cbatt!ucbvax!ULKYVX.BITNET!RDROYA01Show Full Headers
Complete Article Headers
Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Path: arc1-ca.pugleaf.net!utzoo!watmath!clyde!cbatt!ucbvax!ULKYVX.BITNET!RDROYA01 From: RDROYA01@ULKYVX.BITNET.UUCP Newsgroups: comp.sys.atari.st Subject: Uemail source (6 of 12) Message-ID: <8702052237.AA16224@ucbvax.Berkeley.EDU> Date: Thu, 5-Feb-87 06:42:00 EST Article-I.D.: ucbvax.8702052237.AA16224 Posted: Thu Feb 5 06:42:00 1987 Date-Received: Sat, 7-Feb-87 14:49:29 EST Sender: daemon@ucbvax.BERKELEY.EDU Organization: University of Louisville Lines: 1455