home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The C Users' Group Library 1994 August
/
wc-cdrom-cusersgrouplibrary-1994-08.iso
/
vol_100
/
198_02
/
region.c
< prev
next >
Wrap
C/C++ Source or Header
|
1990-01-23
|
15KB
|
482 lines
/*
* 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 "estruct.h"
#include "edef.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 s;
REGION region;
if (curbp->b_mode&MDVIEW) /* don't allow this command if */
return(rdonly()); /* we are in read only mode */
if ((s=getregion(®ion)) != 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 LINE *linep;
register int loffs;
register int s;
REGION region;
if ((s=getregion(®ion)) != 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-- > 0L) {
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;
}
}
mlwrite("[region copied]");
return (TRUE);
}
/* Narrow-to-region (^X-<) makes all but the current region in
the current buffer invisable and unchangable
*/
narrow(f, n)
{
register int status; /* return status */
BUFFER *bp; /* buffer being narrowed */
WINDOW *wp; /* windows to fix up pointers in as well */
REGION creg; /* region boundry structure */
/* find the proper buffer and make sure we aren't already narrow */
bp = curwp->w_bufp; /* find the right buffer */
if (bp->b_flag&BFNAROW) {
mlwrite("%%This buffer is already narrowed");
return(FALSE);
}
/* find the boundries of the current region */
if ((status=getregion(&creg)) != TRUE)
return(status);
curwp->w_dotp = creg.r_linep; /* only by full lines please! */
curwp->w_doto = 0;
creg.r_size += (long)creg.r_offset;
if (creg.r_size <= (long)curwp->w_dotp->l_used) {
mlwrite("%%Must narrow at least 1 full line");
return(FALSE);
}
/* archive the top fragment */
if (bp->b_linep->l_fp != creg.r_linep) {
bp->b_topline = bp->b_linep->l_fp;
creg.r_linep->l_bp->l_fp = (LINE *)NULL;
bp->b_linep->l_fp = creg.r_linep;
creg.r_linep->l_bp = bp->b_linep;
}
/* move forward to the end of this region
(a long number of bytes perhaps) */
while (creg.r_size > (long)32000) {
forwchar(TRUE, 32000);
creg.r_size -= (long)32000;
}
forwchar(TRUE, (int)creg.r_size);
curwp->w_doto = 0; /* only full lines! */
/* archive the bottom fragment */
if (bp->b_linep != curwp->w_dotp) {
bp->b_botline = curwp->w_dotp;
bp->b_botline->l_bp->l_fp = bp->b_linep;
bp->b_linep->l_bp->l_fp = (LINE *)NULL;
bp->b_linep->l_bp = bp->b_botline->l_bp;
}
/* let all the proper windows be updated */
wp = wheadp;
while (wp) {
if (wp->w_bufp == bp) {
wp->w_linep = creg.r_linep;
wp->w_dotp = creg.r_linep;
wp->w_doto = 0;
wp->w_markp = creg.r_linep;
wp->w_marko = 0;
wp->w_flag |= (WFHARD|WFMODE);
}
wp = wp->w_wndp;
}
/* and now remember we are narrowed */
bp->b_flag |= BFNAROW;
mlwrite("[Buffer is narrowed]");
return(TRUE);
}
/* widen-from-region (^X->) restores a narrowed region */
widen(f, n)
{
LINE *lp; /* temp line pointer */
BUFFER *bp; /* buffer being narrowed */
WINDOW *wp; /* windows to fix up pointers in as well */
/* find the proper buffer and make sure we are narrow */
bp = curwp->w_bufp; /* find the right buffer */
if ((bp->b_flag&BFNAROW) == 0) {
mlwrite("%%This buffer is not narrowed");
return(FALSE);
}
/* recover the top fragment */
if (bp->b_topline != (LINE *)NULL) {
lp = bp->b_topline;
while (lp->l_fp != (LINE *)NULL)
lp = lp->l_fp;
lp->l_fp = bp->b_linep->l_fp;
lp->l_fp->l_bp = lp;
bp->b_linep->l_fp = bp->b_topline;
bp->b_topline->l_bp = bp->b_linep;
bp->b_topline = (LINE *)NULL;
}
/* recover the bottom fragment */
if (bp->b_botline != (LINE *)NULL) {
lp = bp->b_botline;
while (lp->l_fp != (LINE *)NULL)
lp = lp->l_fp;
lp->l_fp = bp->b_linep;
bp->b_linep->l_bp->l_fp = bp->b_botline;
bp->b_botline->l_bp = bp->b_linep->l_bp;
bp->b_linep->l_bp = lp;
bp->b_botline = (LINE *)NULL;
}
/* let all the proper windows be updated */
wp = wheadp;
while (wp) {
if (wp->w_bufp == bp)
wp->w_flag |= (WFHARD|WFMODE);
wp = wp->w_wndp;
}
/* and now remember we are not narrowed */
bp->b_flag &= (~BFNAROW);
mlwrite("[Buffer is widened]");
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 LINE *linep;
register int loffs;
register int c;
register int s;
REGION region;
if (curbp->b_mode&MDVIEW) /* don't allow this command if */
return(rdonly()); /* we are in read only mode */
if ((s=getregion(®ion)) != TRUE)
return (s);
lchange(WFHARD);
linep = region.r_linep;
loffs = region.r_offset;
while (region.r_size-- > 0L) {
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 LINE *linep;
register int loffs;
register int c;
register int s;
REGION region;
if (curbp->b_mode&MDVIEW) /* don't allow this command if */
return(rdonly()); /* we are in read only mode */
if ((s=getregion(®ion)) != TRUE)
return (s);
lchange(WFHARD);
linep = region.r_linep;
loffs = region.r_offset;
while (region.r_size-- > 0L) {
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;
long fsize;
long 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 = (long)(curwp->w_marko-curwp->w_doto);
} else {
rp->r_offset = curwp->w_marko;
rp->r_size = (long)(curwp->w_doto-curwp->w_marko);
}
return (TRUE);
}
blp = curwp->w_dotp;
bsize = (long)curwp->w_doto;
flp = curwp->w_dotp;
fsize = (long)(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);
}
#if DECEDT
/*
* Kill the region to the kill buffer, and then remove the mark.
*/
cutregion(f, n)
{
int s;
s = killregion(f, n);
if (s == TRUE) { curwp->w_markp = NULL; curwp->w_marko = 0; }
return(s);
}
/*
* Append the region to the kill buffer, and then kill it.
*/
apkillregion(f, n)
{
lastflag |= CFKILL;
return(killregion(f, n));
}
/*
* Append all of the characters in the
* region to the kill buffer.
*/
apcopyregion(f, n)
{
lastflag |= CFKILL;
return(copyregion(f, n));
}
/*
* Change case in region. 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.
*/
caseregion(f, n)
{
register LINE *linep;
register int loffs;
register int c;
register int s;
REGION region;
if (curbp->b_mode&MDVIEW) /* don't allow this command if */
return(rdonly()); /* we are in read only mode */
if ((s=getregion(®ion)) != TRUE)
return (s);
lchange(WFHARD);
linep = region.r_linep;
loffs = region.r_offset;
while (region.r_size-- > 0L) {
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');
else if (c>='A' && c<='Z')
lputc(linep, loffs, c-'A'+'a');
++loffs;
}
}
return (TRUE);
}
/*
* Ask for a file name, and write the
* contents of the current region to that file.
*
* This function performs the details of file
* writing. Uses the file management routines in the
* "fileio.c" package. The number of lines written is
* displayed. Sadly, it looks inside a LINE; provide
* a macro for this. Most of the grief is error
* checking of some sort.
*/
regionwrite(f, n)
{
register LINE *linep;
register int s;
register int loffs, len;
register int nline;
REGION region;
char fn[NFILEN];
if (restflag) /* don't allow this command if restricted */
return(resterr());
if ((s=getregion(®ion)) != TRUE)
return (s);
if ((s=mlreply("Write file: ", fn, NFILEN)) != TRUE)
return (s);
#if CRYPT
s = resetkey();
if (s != TRUE)
return(s);
#endif
/* turn off ALL keyboard translation in case we get a dos error */
(*term.t_kclose)();
if ((s=ffwopen(fn)) != FIOSUC) { /* Open writes message. */
(*term.t_kopen)();
return (FALSE);
}
mlwrite("[Writing..]"); /* tell us were writing */
nline = 0; /* Number of lines. */
linep = region.r_linep;
loffs = region.r_offset;
while (region.r_size > 0L) {
len = llength(linep) - loffs;
if (len > region.r_size) len = region.r_size;
region.r_size -= (len + 1);
if ((s=ffputline(&linep->l_text[loffs], len)) != FIOSUC)
break;
++nline;
linep = lforw(linep);
loffs = 0;
}
if (s == FIOSUC) { /* No write error. */
s = ffclose();
if (s == FIOSUC) { /* No close error. */
if (nline == 1)
mlwrite("[Wrote 1 line]");
else
mlwrite("[Wrote %d lines]", nline);
}
} else /* Ignore close error */
ffclose(); /* if a write error. */
(*term.t_kopen)();
if (s != FIOSUC) /* Some sort of error. */
return (FALSE);
return (TRUE);
}
#endif