home *** CD-ROM | disk | FTP | other *** search
- #include "jam.h"
- /*
- * 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 "def.h"
-
- static int rn_(getregion,(REGION *rp));
- static int rn_(setsize,(REGION *rp, RSIZE size));
-
- /*
- * 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)
- int f, n;
- {
- register int s;
- REGION region;
-
- if (curbp->b_flag & BFVIEW)
- {
- ttbeep();
- return FALSE;
- }
- if (filetimechanged(curbp))
- return(FALSE);
- clearUndo(curbp);
-
- 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, KFORW));
- }
-
- /*
- * 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)
- int f, n;
- {
- register LINE *linep;
- register int loffs;
- register int s;
- REGION region;
- VOID kdelete();
-
- 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--) {
- 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;
- }
- }
- ewprintf("Region copied.");
- 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)
- int f, n;
- {
- register LINE *linep;
- register int loffs;
- register int c;
- register int s;
- REGION region;
-
- if (curbp->b_flag & BFVIEW)
- {
- ttbeep();
- return FALSE;
- }
- if (filetimechanged(curbp))
- return(FALSE);
- clearUndo(curbp);
-
- if ((s=getregion(®ion)) != TRUE)
- return s;
- lchange(WFHARD);
- linep = region.r_linep;
- loffs = region.r_offset;
- while (region.r_size--) {
- changelineflag(linep, TRUE);
- if (loffs == llength(linep)) {
- linep = lforw(linep);
- loffs = 0;
- } else {
- c = lgetc(linep, loffs);
- if (ISUPPER(c) != FALSE)
- lputc(linep, loffs, (char)TOLOWER(c));
- ++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.
- */
- /*ARGSUSED*/
- upperregion(f, n)
- int f, n;
- {
- register LINE *linep;
- register int loffs;
- register int c;
- register int s;
- REGION region;
- VOID lchange();
-
- if (curbp->b_flag & BFVIEW)
- {
- ttbeep();
- return FALSE;
- }
- if (filetimechanged(curbp))
- return(FALSE);
- clearUndo(curbp);
-
- if ((s=getregion(®ion)) != TRUE)
- return s;
- lchange(WFHARD);
- linep = region.r_linep;
- loffs = region.r_offset;
- while (region.r_size--) {
- changelineflag(linep, TRUE);
- if (loffs == llength(linep)) {
- linep = lforw(linep);
- loffs = 0;
- } else {
- c = lgetc(linep, loffs);
- if (ISLOWER(c) != FALSE)
- lputc(linep, loffs, (char)TOUPPER(c));
- ++loffs;
- }
- }
- 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.
- */
- static int getregion(rp)
- register REGION *rp;
- {
- register LINE *flp;
- register LINE *blp;
- register RSIZE fsize; /* Long now. */
- register RSIZE 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.
- */
- static int setsize(rp, size)
- register REGION *rp;
- register RSIZE size;
- {
-
- rp->r_size = size;
- if (rp->r_size != size) {
- ewprintf("Region is too large");
- return FALSE;
- }
- return TRUE;
- }
-
-