🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

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

Uemail source (3 of 12)

#24758
From: RDROYA01
Date: Wed, 04 Feb 1987 15:06
980 lines
32817 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:
#       basic.c
#       buffer.c
#       region.c
# This archive created: Tue Feb  3 17:41:14 1987
cat << \SHAR_EOF > basic.c
/*
 * The routines in this file
 * move the cursor around on the screen.
 * They compute a new value for the cursor, then
 * adjust ".". The display code always updates the
 * cursor location, so only moves between lines,
 * or functions that adjust the top line in the window
 * and invalidate the framing, are hard.
 */
#include        <stdio.h>
#include        "ed.h"
 
/*
 * Move the cursor to the
 * beginning of the current line
 * or the beginning of the last
 * line if already at beginning.
 * Trivial.
 */
gotobol(f, n)
register int f, n;
{
        if(curwp->w_doto == 0)
                backline(f, n);
        curwp->w_doto  = 0;
        return (TRUE);
}
 
/*
 * Move the cursor backwards by
 * "n" characters. If "n" is less than
 * zero call "forwchar" to actually do the
 * move. Otherwise compute the new cursor
 * location. Error if you try and move
 * out of the buffer. Set the flag if the
 * line pointer for dot changes.
 */
backchar(f, n)
register int    f, n;
{
        register LINE   *lp;
 
        if (n < 0)
                return (forwchar(f, -n));
        while (n--) {
                if (curwp->w_doto == 0) {
                        if ((lp=lback(curwp->w_dotp)) == curbp->b_linep)
                                return (FALSE);
                        curwp->w_dotp  = lp;
                        curwp->w_doto  = llength(lp);
                        curwp->w_flag |= WFMOVE;
                } else
                        curwp->w_doto--;
        }
        return (TRUE);
}
 
/*
 * Move the cursor to the end
 * of the current line or the
 * end of the next line if
 * dot is already at the end.
 * Trivial.  No errors.
 */
gotoeol(f, n)
register int f, n;
{
        if (curwp->w_doto == llength(curwp->w_dotp))
                forwline(f, n);
        curwp->w_doto = llength(curwp->w_dotp);
        return (TRUE);
}
 
/*
 * Move the cursor forwwards by
 * "n" characters. If "n" is less than
 * zero call "backchar" to actually do the
 * move. Otherwise compute the new cursor
 * location, and move ".". Error if you
 * try and move off the end of the
 * buffer. Set the flag if the line pointer
 * for dot changes.
 */
forwchar(f, n)
register int    f, n;
{
        if (n < 0)
                return (backchar(f, -n));
        while (n--) {
                if (curwp->w_doto == llength(curwp->w_dotp)) {
                        if (curwp->w_dotp == curbp->b_linep)
                                return (FALSE);
                        curwp->w_dotp  = lforw(curwp->w_dotp);
                        curwp->w_doto  = 0;
                        curwp->w_flag |= WFMOVE;
                } else
                        curwp->w_doto++;
        }
        return (TRUE);
}
 
/*
 * Goto the beginning of the buffer.
 * Massive adjustment of dot. This is considered
 * to be hard motion; it really isn't if the original
 * value of dot is the same as the new value of dot.
 * Normally bound to "M-<".
 */
gotobob(f, n)
register int f, n;
{
        curwp->w_dotp  = lforw(curbp->b_linep);
        curwp->w_doto  = 0;
        curwp->w_flag |= WFHARD;
        return (TRUE);
}
 
/*
 * Move to the end of the buffer.
 * Dot is always put at the end of the
 * file (ZJ). The standard screen code does
 * most of the hard parts of update. Bound to
 * "M->".
 */
gotoeob(f, n)
register int f, n;
{
        curwp->w_dotp  = curbp->b_linep;
        curwp->w_doto  = 0;
        curwp->w_flag |= WFHARD;
        return (TRUE);
}
 
/*
 * Move forward by full lines.
 * If the number of lines to move is less
 * than zero, call the backward line function to
 * actually do it. The last command controls how
 * the goal column is set. Bound to "C-N". No
 * errors are possible.
 */
forwline(f, n)
register int f, n;
{
        register LINE   *dlp;
 
        if (n < 0)
                return (backline(f, -n));
        if ((lastflag&CFCPCN) == 0)             /* Reset goal if last   */
                curgoal = curcol;               /* not C-P or C-N       */
        thisflag |= CFCPCN;
        dlp = curwp->w_dotp;
        while (n-- && dlp!=curbp->b_linep)
                dlp = lforw(dlp);
        curwp->w_dotp  = dlp;
        curwp->w_doto  = getgoal(dlp);
        curwp->w_flag |= WFMOVE;
        return (TRUE);
}
 
/*
 * This function is like "forwline", but
 * goes backwards. The scheme is exactly the same.
 * Check for arguments that are less than zero and
 * call your alternate. Figure out the new line and
 * call "movedot" to perform the motion. No errors
 * are possible. Bound to "C-P".
 */
backline(f, n)
register int f, n;
{
        register LINE   *dlp;
 
        if (n < 0)
                return (forwline(f, -n));
        if ((lastflag&CFCPCN) == 0)             /* Reset goal if the    */
                curgoal = curcol;               /* last isn't C-P, C-N  */
        thisflag |= CFCPCN;
        dlp = curwp->w_dotp;
        while (n-- && lback(dlp)!=curbp->b_linep)
                dlp = lback(dlp);
        curwp->w_dotp  = dlp;
        curwp->w_doto  = getgoal(dlp);
        curwp->w_flag |= WFMOVE;
        return (TRUE);
}
 
/*
 * This routine, given a pointer to
 * a LINE, and the current cursor goal
 * column, return the best choice for the
 * offset. The offset is returned.
 * Used by "C-N" and "C-P".
 */
getgoal(dlp)
register LINE   *dlp;
{
        register int    c;
        register int    col;
        register int    newcol;
        register int    dbo;
 
        col = 0;
        dbo = 0;
        while (dbo != llength(dlp)) {
                c = lgetc(dlp, dbo);
                newcol = col;
                if (c == '\t')
                        newcol |= 0x07;
                else if (c<0x20 || c==0x7F)
                        ++newcol;
                ++newcol;
                if (newcol > curgoal)
                        break;
                col = newcol;
                ++dbo;
        }
        return (dbo);
}
 
/*
 * Scroll forward by a specified number
 * of lines, or by a full page if no argument.
 * Bound to "C-V". The "2" in the arithmetic on
 * the window size is the overlap; this value is
 * the default overlap value in ITS EMACS.
 * Because this zaps the top line in the display
 * window, we have to do a hard update.
 */
forwpage(f, n)
register int    f, n;
{
        register LINE   *lp;
 
        if (f == FALSE) {
                n = curwp->w_ntrows - 2;        /* Default scroll.      */
                if (n <= 0)                     /* Forget the overlap   */
                        n = 1;                  /* if tiny window.      */
        } else if (n < 0)
                return (backpage(f, -n));
#if     CVMVAS
        else                                    /* Convert from pages   */
                n *= curwp->w_ntrows;           /* to lines.            */
#endif
        lp = curwp->w_linep;
        while (n-- && lp!=curbp->b_linep)
                lp = lforw(lp);
        curwp->w_linep = lp;
        curwp->w_dotp  = lp;
        curwp->w_doto  = 0;
        curwp->w_flag |= WFHARD;
        return (TRUE);
}
 
/*
 * This command is like "forwpage",
 * but it goes backwards. The "2", like above,
 * is the overlap between the two windows. The
 * value is from the ITS EMACS manual. Bound
 * to "M-V". We do a hard update for exactly
 * the same reason.
 */
backpage(f, n)
register int    f, n;
{
        register LINE   *lp;
 
        if (f == FALSE) {
                n = curwp->w_ntrows - 2;        /* Default scroll.      */
                if (n <= 0)                     /* Don't blow up if the */
                        n = 1;                  /* window is tiny.      */
        } else if (n < 0)
                return (forwpage(f, -n));
#if     CVMVAS
        else                                    /* Convert from pages   */
                n *= curwp->w_ntrows;           /* to lines.            */
#endif
        lp = curwp->w_linep;
        while (n-- && lback(lp)!=curbp->b_linep)
                lp = lback(lp);
        curwp->w_linep = lp;
        curwp->w_dotp  = lp;
        curwp->w_doto  = 0;
        curwp->w_flag |= WFHARD;
        return (TRUE);
}
 
/*
 * Set the mark in the current window
 * to the value of "." in the window. No errors
 * are possible. Bound to "M-.".
 */
setmark(f, n)
register int f, n;
{
        curwp->w_markp = curwp->w_dotp;
        curwp->w_marko = curwp->w_doto;
        mlwrite("[Mark set]");
        return (TRUE);
}
 
/*
 * Swap the values of "." and "mark" in
 * the current window. This is pretty easy, bacause
 * all of the hard work gets done by the standard routine
 * that moves the mark about. The only possible error is
 * "no mark". Bound to "C-X C-X".
 */
swapmark(f, n)
register int f, n;
{
        register LINE   *odotp;
        register int    odoto;
 
        if (curwp->w_markp == NULL) {
                mlwrite("No mark in this window");
                return (FALSE);
        }
        odotp = curwp->w_dotp;
        odoto = curwp->w_doto;
        curwp->w_dotp  = curwp->w_markp;
        curwp->w_doto  = curwp->w_marko;
        curwp->w_markp = odotp;
        curwp->w_marko = odoto;
        curwp->w_flag |= WFMOVE;
        return (TRUE);
}
SHAR_EOF
cat << \SHAR_EOF > buffer.c
/*
 * Buffer management.
 * Some of the functions are internal,
 * and some are actually attached to user
 * keys. Like everyone else, they set hints
 * for the display system.
 */
#include        <stdio.h>
#include        "ed.h"
 
/* USEBUFFER eXtended command.  Prompt for buffer name.  Store it in
 * external pattern lastbuf.  Call selbuf() to make the change.  Bound
 * to CTLX-B.
 */
usebuffer(f, n)
register int f, n;
{
        register int    s;
 
        if ((s=readpattern("Use buffer [DEFAULT] ", &lastbuf)) != TRUE)
                return (s);
        return(selbuf(lastbuf));
}
 
/*
 * Attach a buffer to a window. The
 * values of dot and mark come from the buffer
 * if the use count is 0. Otherwise, they come
 * from some other window.
 */
selbuf(bufname)
register char *bufname;
{
        register BUFFER *bp;
        register WINDOW *wp;
 
        /* Find a buffer.  If the buffer does not exist, then ask the user
         * whether a new buffer should be created.
         */
 
        if ((bp=bfind(bufname, MAYBE, 0)) == NULL)
                return (FALSE);
        strcpy(lastbuf, curbp->b_bname);        /* set up for return    */
        if (--curbp->b_nwnd == 0) {             /* Last use.            */
                curbp->b_dotp  = curwp->w_dotp;
                curbp->b_doto  = curwp->w_doto;
                curbp->b_markp = curwp->w_markp;
                curbp->b_marko = curwp->w_marko;
        }
        curbp = bp;                             /* Switch.              */
        curwp->w_bufp  = bp;
        curwp->w_linep = bp->b_linep;           /* For macros, ignored. */
        curwp->w_flag |= WFMODE|WFFORCE|WFHARD; /* Quite nasty.         */
        if (bp->b_nwnd++ == 0) {                /* First use.           */
                curwp->w_dotp  = bp->b_dotp;
                curwp->w_doto  = bp->b_doto;
                curwp->w_markp = bp->b_markp;
                curwp->w_marko = bp->b_marko;
                return (TRUE);
        }
        wp = wheadp;                            /* Look for old.        */
        while (wp != NULL) {
                if (wp!=curwp && wp->w_bufp==bp) {
                        curwp->w_dotp  = wp->w_dotp;
                        curwp->w_doto  = wp->w_doto;
                        curwp->w_markp = wp->w_markp;
                        curwp->w_marko = wp->w_marko;
                        break;
                }
                wp = wp->w_wndp;
        }
        return (TRUE);
}
 
/* KILLBUFFER  eXtended command.  Prompt for buffer name.  Call delbuf()
 * to do the actual kill.  Bound to CTLX-K.
 */
killbuffer(f, n)
register int f, n;
{
        register int    s;
 
        if ((s=readpattern("Kill buffer [DEFAULT] ", &lastbuf)) != TRUE)
                return (s);
        return(delbuf(lastbuf));
}
 
/*
 * Dispose of a buffer, by name.
 * Look up bufname (don't get too
 * upset if it isn't there at all!). Get quite upset
 * if the buffer is being displayed. Clear the buffer (ask
 * if the buffer has been changed). Then free the header
 * line and the buffer header.
 */
delbuf(bufname)
register char *bufname;
{
        register BUFFER *bp;
        register BUFFER *bp1;
        register BUFFER *bp2;
        register int    s;
 
        if ((bp=bfind(bufname, FALSE, 0)) == NULL)      /* Easy if unknown.*/
                return (TRUE);
        strcpy(lastbuf, curbp->b_bname);
        if (bp->b_nwnd != 0) {                  /* Error if on screen.  */
                mlwrite("Buffer is being displayed");
                return (FALSE);
        }
        if ((s=bclear(bp)) != TRUE)             /* Blow text away.      */
                return (s);
        free((char *) bp->b_linep);             /* Release header line. */
        bp1 = NULL;                             /* Find the header.     */
        bp2 = bheadp;
        while (bp2 != bp) {
                bp1 = bp2;
                bp2 = bp2->b_bufp;
        }
        bp2 = bp2->b_bufp;                      /* Next one in chain.   */
        if (bp1 == NULL)                        /* Unlink it.           */
                bheadp = bp2;
        else
                bp1->b_bufp = bp2;
        free((char *) bp);                      /* Release buffer block */
        return (TRUE);
}
 
/*
 * List all of the active
 * buffers. First update the special
 * buffer that holds the list. Next make
 * sure at least 1 window is displaying the
 * buffer list, splitting the screen if this
 * is what it takes. Lastly, repaint all of
 * the windows that are displaying the
 * list. Bound to "C-X C-B".
 */
listbuffers(f, n)
register int f, n;
{
        register WINDOW *wp;
        register BUFFER *bp;
        register int    s;
 
        if (blistp == NULL)
                {
                blistp = bfind("[List]", TRUE, BFTEMP); /* Buffer list buffer*/
                if (blistp == NULL)
                        return(ABORT);
                }
        if ((s=makelist()) != TRUE)
                return (s);
        if (blistp->b_nwnd == 0) {              /* Not on screen yet.   */
                if ((wp=wpopup()) == NULL)
                        return (FALSE);
                bp = wp->w_bufp;
                if (--bp->b_nwnd == 0) {
                        bp->b_dotp  = wp->w_dotp;
                        bp->b_doto  = wp->w_doto;
                        bp->b_markp = wp->w_markp;
                        bp->b_marko = wp->w_marko;
                }
                wp->w_bufp  = blistp;
                ++blistp->b_nwnd;
        }
        wp = wheadp;
        while (wp != NULL) {
                if (wp->w_bufp == blistp) {
                        wp->w_linep = lforw(blistp->b_linep);
                        wp->w_dotp  = lforw(blistp->b_linep);
                        wp->w_doto  = 0;
                        wp->w_markp = NULL;
                        wp->w_marko = 0;
                        wp->w_flag |= WFMODE|WFHARD;
                }
                wp = wp->w_wndp;
        }
        return (TRUE);
}
 
/*
 * This routine rebuilds the
 * text in the special secret buffer
 * that holds the buffer list. It is called
 * by the list buffers command. Return TRUE
 * if everything works. Return FALSE if there
 * is an error (if there is no memory).
 */
makelist()
{
        register char   *cp1;
        register char   *cp2;
        register int    c;
        register BUFFER *bp;
        register LINE   *lp;
        register long   nbytes;
        register int    s;
        register int    type;
        char            b[6+1];
        char            line[128];
 
        blistp->b_flag &= ~BFCHG;               /* Don't complain!      */
        blistp->b_bmode |= BMNWRAP;
        if ((s=bclear(blistp)) != TRUE)         /* Blow old text away   */
                return (s);
        strcpy(blistp->b_fname, "");
        if (addline(blistp,"C   Size Buffer           File") == FALSE
        ||  addline(blistp,"-   ---- ------           ----") == FALSE)
                return (FALSE);
        bp = bheadp;                            /* For all buffers      */
        while (bp != NULL) {
                if ((bp->b_flag&BFTEMP) != 0) { /* Skip magic ones.     */
                        bp = bp->b_bufp;
                        continue;
                }
                cp1 = &line[0];                 /* Start at left edge   */
                if ((bp->b_flag&BFCHG) != 0)    /* "*" if changed       */
                        *cp1++ = '*';
                else
                        *cp1++ = ' ';
                *cp1++ = ' ';                   /* Gap.                 */
                nbytes = 0L;                    /* Count bytes in buf.  */
                lp = lforw(bp->b_linep);
                while (lp != bp->b_linep) {
                        nbytes += llength(lp)+1;
                        lp = lforw(lp);
                }
                ltoa(b, 6, nbytes);             /* 6 digit buffer size. */
                cp2 = &b[0];
                while ((c = *cp2++) != 0)
                        *cp1++ = c;
                *cp1++ = ' ';                   /* Gap.                 */
                cp2 = &bp->b_bname[0];          /* Buffer name          */
                while ((c = *cp2++) != 0)
                        *cp1++ = c;
                cp2 = &bp->b_fname[0];          /* File name            */
                if (*cp2 != 0) {
                        while (cp1 < &line[1+1+6+1+NBUFN+1])
                                *cp1++ = ' ';
                        while ((c = *cp2++) != 0) {
                                if (cp1 < &line[128-1])
                                        *cp1++ = c;
                        }
                }
                *cp1 = 0;                       /* Add to the buffer.   */
                if (addline(blistp, line) == FALSE)
                        return (FALSE);
                bp = bp->b_bufp;
        }
        return (TRUE);                          /* All done             */
}
 
ltoa(buf, width, num)
register char   buf[];
register int    width;
register long   num;
{
        buf[width] = 0;                         /* End of string.       */
        while (num >= 10L) {                    /* Conditional digits.  */
                buf[--width] = (int)(num%10L) + '0';
                num /= 10L;
        }
        buf[--width] = num + '0';               /* Always 1 digit.      */
        while (width != 0)                      /* Pad with blanks.     */
                buf[--width] = ' ';
}
 
/*
 * The argument "text" points to
 * a string. Append this line to the
 * buffer "bp" (one with BFTEMP set). Handcraft the EOL
 * on the end. Return TRUE if it worked and
 * FALSE if you ran out of room.
 */
addline(bp, text)
register BUFFER *bp;
register char *text;
{
        register LINE   *lp;
        register int    i;
        register int    ntext;
 
        ntext = strlen(text);
        if ((lp=lalloc(ntext)) == NULL)
                return (FALSE);
        for (i=0; i<ntext; ++i)
                lputc(lp, i, text[i]);
        bp->b_linep->l_bp->l_fp = lp;   /* Hook onto the end    */
        lp->l_bp = bp->b_linep->l_bp;
        bp->b_linep->l_bp = lp;
        lp->l_fp = bp->b_linep;
        if (bp->b_dotp == bp->b_linep)  /* If "." is at the end */
                bp->b_dotp = lp;                /* move it to new line  */
        return (TRUE);
}
 
/*
 * Look through the list of
 * buffers. Return TRUE if there
 * are any changed buffers. Buffers
 * that hold magic internal stuff are
 * not considered; who cares if the
 * list of buffer names is hacked.
 * Return FALSE if no buffers
 * have been changed.
 */
anycb()
{
        register BUFFER *bp;
 
        bp = bheadp;
        while (bp != NULL) {
                if ((bp->b_flag&BFTEMP)==0 && (bp->b_flag&BFCHG)!=0)
                        return (TRUE);
                bp = bp->b_bufp;
        }
        return (FALSE);
}
 
/*
 * Find a buffer, by name. Return a pointer
 * to the BUFFER structure associated with it. If
 * the named buffer is found, but is a TEMP buffer (like
 * the buffer list) conplain. If the buffer is not found
 * and the "cflag" is TRUE, create it. The "bflag" is
 * the settings for the flags in in buffer.
 */
BUFFER  *
bfind(bname, cflag, bflag)
register char   *bname;
register int cflag, bflag;
{
        register BUFFER *bp;
        register LINE   *lp;
        char    *index(),*ptr;
 
        bp = bheadp;
        while (bp != NULL)
                {
                if (strcmp(bname, bp->b_bname) == 0)
                        {
                        if ((bp->b_flag&BFTEMP) != 0)
                                if (cflag == FALSE)
                                        {
                                        mlwrite("Cannot select builtin buffer");
                                        return (FALSE);
                                        }
                        return (bp);
                        }
                bp = bp->b_bufp;
                }
        /* Buffer does not exist.  Prompt the user to see if a new
         * buffer should be created.
         */
        if (cflag == MAYBE) {
                if (mlyesno("Create new buffer") != TRUE)
                        return(FALSE);
                cflag = TRUE;   /* yes, create it */
                }
        if (cflag == TRUE) {
                if ((bp=(BUFFER *)malloc(sizeof(BUFFER))) == NULL)
                        return (NULL);
                if ((lp=lalloc(0)) == NULL) {
                        free((char *) bp);
                        return (NULL);
                }
                /* clear all mode flags */
                bp->b_bmode &=~BMWRAP;
                bp->b_bmode &=~BMNWRAP;
                bp->b_bmode &=~BMCMODE;
                if (ptr=index(bname,'.'))
                        {
                        if (strncmp(ptr, ".mss",4)==0)
                                bp->b_bmode |= BMWRAP;
                        else if (strcmp(ptr,".c")==0)
                                bp->b_bmode |= BMCMODE;
                        else if (strcmp(ptr,".h")==0)
                                bp->b_bmode |= BMCMODE;
                        else
                                bp->b_bmode |= glmode;
                        }
                else
                        bp->b_bmode |= glmode;
                bp->b_bufp  = bheadp;
                bheadp = bp;
                bp->b_dotp  = lp;
                bp->b_doto  = 0;
                bp->b_markp = lp;       /* All new buffers begin with mark */
                bp->b_marko = 0;
                bp->b_flag  = bflag;
                bp->b_nwnd  = 0;
                bp->b_linep = lp;
                strcpy(bp->b_fname, "");
                strcpy(bp->b_bname, bname);
                lp->l_fp = lp;
                lp->l_bp = lp;
        }
        return (bp);
}
 
/*
 * This routine blows away all of the text
 * in a buffer. If the buffer is marked as changed
 * then we ask if it is ok to blow it away; this is
 * to save the user the grief of losing text. The
 * window chain is nearly always wrong if this gets
 * called; the caller must arrange for the updates
 * that are required. Return TRUE if everything
 * looks good.
 */
bclear(bp)
register BUFFER *bp;
{
        register LINE   *lp;
        register int    s;
 
        if ((bp->b_flag&BFTEMP) == 0            /* Not scratch buffer.  */
        && (bp->b_flag&BFCHG) != 0              /* Something changed    */
        && (s=mlyesno("Discard changes")) != TRUE)
                return (s);
        bp->b_flag  &= ~BFCHG;                  /* Not changed          */
        while ((lp=lforw(bp->b_linep)) != bp->b_linep)
                lfree(lp);
        bp->b_dotp  = bp->b_linep;              /* Fix "."              */
        bp->b_doto  = 0;
        bp->b_markp = NULL;                     /* Invalidate "mark"    */
        bp->b_marko = 0;
        return (TRUE);
}
SHAR_EOF
cat << \SHAR_EOF > region.c
/*
 * The routines in this file
 * deal with the region, that magic space
 * between "." and mark. Some functions are
 * commands. Some functions are just for
 * internal use.
 */
#include        <stdio.h>
#include        "ed.h"
 
/*
 * Kill the region. Ask "getregion"
 * to figure out the bounds of the region.
 * Move "." to the start, and kill the characters.
 * Bound to "C-W".
 */
killregion(f, n)
register int f, n;
{
        register int    s;
        REGION          region;
 
        if ((s=getregion(&region)) != TRUE)
                return (s);
        if ((lastflag&CFKILL) == 0)             /* This is a kill type  */
                kdelete();                      /* command, so do magic */
        thisflag |= CFKILL;                     /* kill buffer stuff.   */
        curwp->w_dotp = region.r_linep;
        curwp->w_doto = region.r_offset;
        return (ldelete(region.r_size, TRUE));
}
 
/*
 * Copy all of the characters in the
 * region to the kill buffer. Don't move dot
 * at all. This is a bit like a kill region followed
 * by a yank. Bound to "M-W".
 */
copyregion(f, n)
register int f, n;
{
        register LINE   *linep;
        register int    loffs;
        register int    s;
        REGION          region;
 
        if ((s=getregion(&region)) != TRUE)
                return (s);
        if ((lastflag&CFKILL) == 0)             /* Kill type command.   */
                kdelete();
        thisflag |= CFKILL;
        linep = region.r_linep;                 /* Current line.        */
        loffs = region.r_offset;                /* Current offset.      */
        while (region.r_size--) {
                if (loffs == llength(linep)) {  /* End of line.         */
                        if ((s=kinsert('\n')) != TRUE)
                                return (s);
                        linep = lforw(linep);
                        loffs = 0;
                } else {                        /* Middle of line.      */
                        if ((s=kinsert(lgetc(linep, loffs))) != TRUE)
                                return (s);
                        ++loffs;
                }
        }
        return (TRUE);
}
 
/*
 * Lower case region. Zap all of the upper
 * case characters in the region to lower case. Use
 * the region code to set the limits. Scan the buffer,
 * doing the changes. Call "lchange" to ensure that
 * redisplay is done in all buffers. Bound to
 * "C-X C-L".
 */
lowerregion(f, n)
register int f, n;
{
        register LINE   *linep;
        register int    loffs;
        register int    c;
        register int    s;
        REGION          region;
 
        if ((s=getregion(&region)) != TRUE)
                return (s);
        lchange(WFHARD);
        linep = region.r_linep;
        loffs = region.r_offset;
        while (region.r_size--) {
                if (loffs == llength(linep)) {
                        linep = lforw(linep);
                        loffs = 0;
                } else {
                        c = lgetc(linep, loffs);
                        if (c>='A' && c<='Z')
                                lputc(linep, loffs, c+'a'-'A');
                        ++loffs;
                }
        }
        return (TRUE);
}
 
/*
 * Upper case region. Zap all of the lower
 * case characters in the region to upper case. Use
 * the region code to set the limits. Scan the buffer,
 * doing the changes. Call "lchange" to ensure that
 * redisplay is done in all buffers. Bound to
 * "C-X C-L".
 */
upperregion(f, n)
register int f, n;
{
        register LINE   *linep;
        register int    loffs;
        register int    c;
        register int    s;
        REGION          region;
 
        if ((s=getregion(&region)) != TRUE)
                return (s);
        lchange(WFHARD);
        linep = region.r_linep;
        loffs = region.r_offset;
        while (region.r_size--) {
                if (loffs == llength(linep)) {
                        linep = lforw(linep);
                        loffs = 0;
                } else {
                        c = lgetc(linep, loffs);
                        if (c>='a' && c<='z')
                                lputc(linep, loffs, c-'a'+'A');
                        ++loffs;
                }
        }
        return (TRUE);
}
 
/*
 * This routine figures out the
 * bounds of the region in the current window, and
 * fills in the fields of the "REGION" structure pointed
 * to by "rp". Because the dot and mark are usually very
 * close together, we scan outward from dot looking for
 * mark. This should save time. Return a standard code.
 * Callers of this routine should be prepared to get
 * an "ABORT" status; we might make this have the
 * conform thing later.
 */
getregion(rp)
register REGION *rp;
{
        register LINE   *flp;
        register LINE   *blp;
        register int    fsize;
        register int    bsize;
 
        if (curwp->w_markp == NULL) {
                mlwrite("No mark set in this window");
                return (FALSE);
        }
        if (curwp->w_dotp == curwp->w_markp) {
                rp->r_linep = curwp->w_dotp;
                if (curwp->w_doto < curwp->w_marko) {
                        rp->r_offset = curwp->w_doto;
                        rp->r_size = curwp->w_marko-curwp->w_doto;
                } else {
                        rp->r_offset = curwp->w_marko;
                        rp->r_size = curwp->w_doto-curwp->w_marko;
                }
                return (TRUE);
        }
        blp = curwp->w_dotp;
        bsize = curwp->w_doto;
        flp = curwp->w_dotp;
        fsize = llength(flp)-curwp->w_doto+1;
        while (flp!=curbp->b_linep || lback(blp)!=curbp->b_linep) {
                if (flp != curbp->b_linep) {
                        flp = lforw(flp);
                        if (flp == curwp->w_markp) {
                                rp->r_linep = curwp->w_dotp;
                                rp->r_offset = curwp->w_doto;
                                rp->r_size = fsize+curwp->w_marko;
                                return (TRUE);
                        }
                        fsize += llength(flp)+1;
                }
                if (lback(blp) != curbp->b_linep) {
                        blp = lback(blp);
                        bsize += llength(blp)+1;
                        if (blp == curwp->w_markp) {
                                rp->r_linep = blp;
                                rp->r_offset = curwp->w_marko;
                                rp->r_size = bsize - curwp->w_marko;
                                return (TRUE);
                        }
                }
        }
        mlwrite("Bug: lost mark");
        return (FALSE);
}
SHAR_EOF
#       End of shell archive
exit 0
%NONAME-W-NOMSG, Message number 00000000
Technical Details
Message-ID: <8702041623.AA16202@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 (3 of 12)
Message-ID: <8702041623.AA16202@ucbvax.Berkeley.EDU>
Date: Wed, 4-Feb-87 10:06:00 EST
Article-I.D.: ucbvax.8702041623.AA16202
Posted: Wed Feb  4 10:06:00 1987
Date-Received: Sat, 7-Feb-87 05:06:18 EST
Sender: daemon@ucbvax.BERKELEY.EDU
Organization: University of Louisville
Lines: 980