home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Frozen Fish 1: Amiga
/
FrozenFish-Apr94.iso
/
bbs
/
alib
/
d3xx
/
d352
/
mg.lha
/
MG
/
src.LZH
/
mg
/
region.c
< prev
next >
Wrap
C/C++ Source or Header
|
1990-05-23
|
8KB
|
296 lines
/*
* Region based commands. 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 "prefixregion.h"
#include "def.h"
#include "line.h"
#include "region.h"
#include "buffer.h"
#include "window.h"
#ifdef ANSI
#include <string.h>
#endif
/*
* Kill the region. Ask "getregion" to figure out the bounds of the region.
* Move "." to the start, and kill the characters.
*/
/* ARGSUSED */
killregion(f, n)
{
register int s;
struct region reg;
if ((s = getregion(®)) != 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 = reg.r_linep;
curwp->w_doto = reg.r_offset;
return (fdelete(reg.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.
*/
/* ARGSUSED */
copyregion(f, n)
{
register struct line *linep;
register int loffs;
register int s;
struct region reg;
VOID kdelete();
if ((s = getregion(®)) != TRUE)
return s;
if ((lastflag & CFKILL) == 0) /* Kill type command. */
kdelete();
thisflag |= CFKILL;
linep = reg.r_linep; /* Current line. */
loffs = reg.r_offset; /* Current offset. */
while (reg.r_size--) {
if (loffs == llength(linep)) { /* End of line. */
if ((s = kinsert('\n', KFORW)) != TRUE)
return (s);
linep = lforw(linep);
loffs = 0;
} else { /* Middle of line. */
if ((s = kinsert(lgetc(linep, loffs), KFORW)) != TRUE)
return s;
loffs += 1;
}
}
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.
*/
/* ARGSUSED */
lowerregion(f, n)
{
register struct line *linep;
register int loffs;
register int c;
register int s;
struct region reg;
if ((s = getregion(®)) != TRUE)
return s;
lchange(WFHARD);
linep = reg.r_linep;
loffs = reg.r_offset;
while (reg.r_size--) {
if (loffs == llength(linep)) {
linep = lforw(linep);
loffs = 0;
} else {
c = lgetc(linep, loffs);
if (ISUPPER(c) != FALSE)
lputc(linep, loffs, TOLOWER(c));
loffs += 1;
}
}
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.
*/
/* ARGSUSED */
upperregion(f, n)
{
register struct line *linep;
register int loffs;
register int c;
register int s;
struct region reg;
VOID lchange();
if ((s = getregion(®)) != TRUE)
return s;
lchange(WFHARD);
linep = reg.r_linep;
loffs = reg.r_offset;
while (reg.r_size--) {
if (loffs == llength(linep)) {
linep = lforw(linep);
loffs = 0;
} else {
c = lgetc(linep, loffs);
if (ISLOWER(c) != FALSE)
lputc(linep, loffs, TOUPPER(c));
loffs += 1;
}
}
return TRUE;
}
/*
* This routine figures out the bound of the region in the current window,
* and stores the results into the fields of the REGION structure. Dot and
* mark are usually close together, but I don't know the order, so I scan
* outward from dot, in both directions, looking for mark. The size is kept
* in a long. At the end, after the size is figured out, it is assigned to
* the size field of the region structure. If this assignment loses any bits,
* then we print an error. This is "type independent" overflow checking. All
* of the callers of this routine should be ready to get an ABORT status,
* because I might add a "if regions is big, ask before clobberring" flag.
*/
getregion(rp)
register struct region *rp;
{
register struct line *flp;
register struct line *blp;
register long fsize; /* Long now. */
register long bsize;
if (curwp->w_markp == NULL) {
ewprintf("No mark set in this window");
return (FALSE);
}
if (curwp->w_dotp == curwp->w_markp) { /* "r_size" always ok. */
rp->r_linep = curwp->w_dotp;
if (curwp->w_doto < curwp->w_marko) {
rp->r_offset = curwp->w_doto;
rp->r_size = (RSIZE) (curwp->w_marko - curwp->w_doto);
} else {
rp->r_offset = curwp->w_marko;
rp->r_size = (RSIZE) (curwp->w_doto - curwp->w_marko);
}
return TRUE;
}
flp = blp = curwp->w_dotp; /* Get region size. */
bsize = curwp->w_doto;
fsize = llength(flp) - curwp->w_doto + 1;
while (lforw(flp) != curbp->b_linep || lback(blp) != curbp->b_linep) {
if (lforw(flp) != curbp->b_linep) {
flp = lforw(flp);
if (flp == curwp->w_markp) {
rp->r_linep = curwp->w_dotp;
rp->r_offset = curwp->w_doto;
return (setsize(rp,
(RSIZE) (fsize + curwp->w_marko)));
}
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;
return (setsize(rp,
(RSIZE) (bsize - curwp->w_marko)));
}
}
}
ewprintf("Bug: lost mark"); /* Gak! */
return FALSE;
}
/*
* Set size, and check for overflow.
*/
setsize(rp, size)
register struct region *rp;
register RSIZE size;
{
rp->r_size = size;
if (rp->r_size != size) {
ewprintf("Region is too large");
return FALSE;
}
return TRUE;
}
#ifdef PREFIXREGION
/*
* Implements one of my favorite keyboard macros; put a string at the
* beginning of a number of lines in a buffer. The quote string is settable
* by using set-prefix-string. Great for quoting mail, which is the real
* reason I wrote it, but also has uses for creating bar comments (like the
* one you're reading) in C code.
*/
#define PREFIXLENGTH 40
static char prefix_string[PREFIXLENGTH] = {'>', '\0'};
/*
* Prefix the region with whatever is in prefix_string. Leaves dot at the
* beginning of the line after the end of the region. If an argument is
* given, prompts for the line prefix string.
*/
/* ARGSUSED */
prefixregion(f, n)
{
register int s;
register struct line *first, *last;
register int nline;
struct region reg;
char *prefix = prefix_string;
if ((f == TRUE) && ((s = setprefix(FFRAND, 1)) != TRUE))
return s;
/* get # of lines to affect */
if ((s = getregion(®)) != TRUE)
return (s);
first = reg.r_linep;
last = (first == curwp->w_dotp) ? curwp->w_markp : curwp->w_dotp;
for (nline = 1; first != last; nline += 1)
first = lforw(first);
/* move to beginning of region */
curwp->w_dotp = reg.r_linep;
curwp->w_doto = reg.r_offset;
/* for each line, go to beginning and insert the prefix string */
while (nline--) {
(VOID) gotobol(FFRAND, 1);
for (prefix = prefix_string; *prefix; prefix += 1)
(VOID) linsert(1, *prefix);
(VOID) forwline(FFRAND, 1);
}
(VOID) gotobol(FFRAND, 1);
return TRUE;
}
/*
* Set prefix string.
*/
/* ARGSUSED */
setprefix(f, n)
{
char buf[PREFIXLENGTH];
register int s;
if (prefix_string[0] == '\0')
s = ereply("Prefix string: ", buf, sizeof buf);
else
s = ereply("Prefix string (default %s): ",
buf, sizeof buf, prefix_string);
if (s == TRUE)
(VOID) strcpy(prefix_string, buf);
if ((s == FALSE) && (prefix_string[0] != '\0')) /* CR -- use old one */
s = TRUE;
return s;
}
#endif