🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: comp.sys.atari.st
Article #24780

Uemail source (6 of 12)

#24780
From: RDROYA01
Date: Thu, 05 Feb 1987 11:42
1455 lines
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!RDROYA01

Show 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