home *** CD-ROM | disk | FTP | other *** search
- /*
- * 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
-