Annotation of src/usr.bin/mg/region.c, Revision 1.2
1.1 deraadt 1: /*
2: * Region based commands.
3: * The routines in this file
4: * deal with the region, that magic space
5: * between "." and mark. Some functions are
6: * commands. Some functions are just for
7: * internal use.
8: */
9: #include "def.h"
10:
11: /*
12: * Kill the region. Ask "getregion"
13: * to figure out the bounds of the region.
14: * Move "." to the start, and kill the characters.
15: */
1.2 ! millert 16: /* ARGSUSED */
1.1 deraadt 17: killregion(f, n)
18: {
1.2 ! millert 19: register int s;
! 20: REGION region;
1.1 deraadt 21:
1.2 ! millert 22: if ((s = getregion(®ion)) != TRUE)
1.1 deraadt 23: return (s);
1.2 ! millert 24: if ((lastflag & CFKILL) == 0) /* This is a kill type */
! 25: kdelete(); /* command, so do magic */
! 26: thisflag |= CFKILL; /* kill buffer stuff. */
1.1 deraadt 27: curwp->w_dotp = region.r_linep;
28: curwp->w_doto = region.r_offset;
29: return (ldelete(region.r_size, KFORW));
30: }
31:
32: /*
33: * Copy all of the characters in the
34: * region to the kill buffer. Don't move dot
35: * at all. This is a bit like a kill region followed
36: * by a yank.
37: */
1.2 ! millert 38: /* ARGSUSED */
1.1 deraadt 39: copyregion(f, n)
40: {
1.2 ! millert 41: register LINE *linep;
! 42: register int loffs;
! 43: register int s;
! 44: REGION region;
! 45: VOID kdelete();
1.1 deraadt 46:
1.2 ! millert 47: if ((s = getregion(®ion)) != TRUE)
1.1 deraadt 48: return s;
1.2 ! millert 49: if ((lastflag & CFKILL) == 0) /* Kill type command. */
1.1 deraadt 50: kdelete();
51: thisflag |= CFKILL;
1.2 ! millert 52: linep = region.r_linep; /* Current line. */
! 53: loffs = region.r_offset;/* Current offset. */
1.1 deraadt 54: while (region.r_size--) {
1.2 ! millert 55: if (loffs == llength(linep)) { /* End of line. */
! 56: if ((s = kinsert('\n', KFORW)) != TRUE)
1.1 deraadt 57: return (s);
58: linep = lforw(linep);
59: loffs = 0;
1.2 ! millert 60: } else { /* Middle of line. */
! 61: if ((s = kinsert(lgetc(linep, loffs), KFORW)) != TRUE)
1.1 deraadt 62: return s;
63: ++loffs;
64: }
65: }
66: return TRUE;
67: }
68:
69: /*
70: * Lower case region. Zap all of the upper
71: * case characters in the region to lower case. Use
72: * the region code to set the limits. Scan the buffer,
73: * doing the changes. Call "lchange" to ensure that
74: * redisplay is done in all buffers.
75: */
1.2 ! millert 76: /* ARGSUSED */
1.1 deraadt 77: lowerregion(f, n)
78: {
1.2 ! millert 79: register LINE *linep;
! 80: register int loffs;
! 81: register int c;
! 82: register int s;
! 83: REGION region;
1.1 deraadt 84:
1.2 ! millert 85: if ((s = getregion(®ion)) != TRUE)
1.1 deraadt 86: return s;
87: lchange(WFHARD);
88: linep = region.r_linep;
89: loffs = region.r_offset;
90: while (region.r_size--) {
91: if (loffs == llength(linep)) {
92: linep = lforw(linep);
93: loffs = 0;
94: } else {
95: c = lgetc(linep, loffs);
96: if (ISUPPER(c) != FALSE)
97: lputc(linep, loffs, TOLOWER(c));
98: ++loffs;
99: }
100: }
101: return TRUE;
102: }
103:
104: /*
105: * Upper case region. Zap all of the lower
106: * case characters in the region to upper case. Use
107: * the region code to set the limits. Scan the buffer,
108: * doing the changes. Call "lchange" to ensure that
109: * redisplay is done in all buffers.
110: */
1.2 ! millert 111: /* ARGSUSED */
1.1 deraadt 112: upperregion(f, n)
113: {
1.2 ! millert 114: register LINE *linep;
! 115: register int loffs;
! 116: register int c;
! 117: register int s;
! 118: REGION region;
! 119: VOID lchange();
1.1 deraadt 120:
1.2 ! millert 121: if ((s = getregion(®ion)) != TRUE)
1.1 deraadt 122: return s;
123: lchange(WFHARD);
124: linep = region.r_linep;
125: loffs = region.r_offset;
126: while (region.r_size--) {
127: if (loffs == llength(linep)) {
128: linep = lforw(linep);
129: loffs = 0;
130: } else {
131: c = lgetc(linep, loffs);
132: if (ISLOWER(c) != FALSE)
133: lputc(linep, loffs, TOUPPER(c));
134: ++loffs;
135: }
136: }
137: return TRUE;
138: }
139:
140: /*
141: * This routine figures out the bound of the region
142: * in the current window, and stores the results into the fields
143: * of the REGION structure. Dot and mark are usually close together,
144: * but I don't know the order, so I scan outward from dot, in both
145: * directions, looking for mark. The size is kept in a long. At the
146: * end, after the size is figured out, it is assigned to the size
147: * field of the region structure. If this assignment loses any bits,
148: * then we print an error. This is "type independent" overflow
149: * checking. All of the callers of this routine should be ready to
150: * get an ABORT status, because I might add a "if regions is big,
151: * ask before clobberring" flag.
152: */
1.2 ! millert 153: getregion(rp)
! 154: register REGION *rp;
! 155: {
! 156: register LINE *flp;
! 157: register LINE *blp;
! 158: register long fsize; /* Long now. */
! 159: register long bsize;
1.1 deraadt 160:
161: if (curwp->w_markp == NULL) {
162: ewprintf("No mark set in this window");
163: return (FALSE);
164: }
1.2 ! millert 165: if (curwp->w_dotp == curwp->w_markp) { /* "r_size" always ok. */
1.1 deraadt 166: rp->r_linep = curwp->w_dotp;
167: if (curwp->w_doto < curwp->w_marko) {
168: rp->r_offset = curwp->w_doto;
1.2 ! millert 169: rp->r_size = (RSIZE) (curwp->w_marko - curwp->w_doto);
1.1 deraadt 170: } else {
171: rp->r_offset = curwp->w_marko;
1.2 ! millert 172: rp->r_size = (RSIZE) (curwp->w_doto - curwp->w_marko);
1.1 deraadt 173: }
174: return TRUE;
175: }
1.2 ! millert 176: flp = blp = curwp->w_dotp; /* Get region size. */
1.1 deraadt 177: bsize = curwp->w_doto;
1.2 ! millert 178: fsize = llength(flp) - curwp->w_doto + 1;
! 179: while (lforw(flp) != curbp->b_linep || lback(blp) != curbp->b_linep) {
1.1 deraadt 180: if (lforw(flp) != curbp->b_linep) {
181: flp = lforw(flp);
182: if (flp == curwp->w_markp) {
183: rp->r_linep = curwp->w_dotp;
184: rp->r_offset = curwp->w_doto;
185: return (setsize(rp,
1.2 ! millert 186: (RSIZE) (fsize + curwp->w_marko)));
1.1 deraadt 187: }
1.2 ! millert 188: fsize += llength(flp) + 1;
1.1 deraadt 189: }
190: if (lback(blp) != curbp->b_linep) {
191: blp = lback(blp);
1.2 ! millert 192: bsize += llength(blp) + 1;
1.1 deraadt 193: if (blp == curwp->w_markp) {
194: rp->r_linep = blp;
195: rp->r_offset = curwp->w_marko;
196: return (setsize(rp,
1.2 ! millert 197: (RSIZE) (bsize - curwp->w_marko)));
1.1 deraadt 198: }
199: }
200: }
1.2 ! millert 201: ewprintf("Bug: lost mark"); /* Gak! */
1.1 deraadt 202: return FALSE;
203: }
204:
205: /*
206: * Set size, and check for overflow.
207: */
1.2 ! millert 208: setsize(rp, size)
! 209: register REGION *rp;
! 210: register RSIZE size;
! 211: {
1.1 deraadt 212:
213: rp->r_size = size;
214: if (rp->r_size != size) {
215: ewprintf("Region is too large");
216: return FALSE;
217: }
218: return TRUE;
219: }
220:
221: #ifdef PREFIXREGION
222: /*
223: * Implements one of my favorite keyboard macros; put a string at the
224: * beginning of a number of lines in a buffer. The quote string is
225: * settable by using set-prefix-string. Great for quoting mail, which
226: * is the real reason I wrote it, but also has uses for creating bar
227: * comments (like the one you're reading) in C code.
228: */
229:
230: #define PREFIXLENGTH 40
1.2 ! millert 231: static char prefix_string[PREFIXLENGTH] = {'>', '\0'};
1.1 deraadt 232:
233: /*
234: * Prefix the region with whatever is in prefix_string.
235: * Leaves dot at the beginning of the line after the end
236: * of the region. If an argument is given, prompts for the
237: * line prefix string.
238: */
239:
1.2 ! millert 240: /* ARGSUSED */
1.1 deraadt 241: prefixregion(f, n)
242: {
1.2 ! millert 243: register int s;
! 244: register LINE *first, *last;
! 245: register int nline;
! 246: REGION region;
! 247: char *prefix = prefix_string;
1.1 deraadt 248:
249: if ((f == TRUE) && ((s = setprefix(FFRAND, 1)) != TRUE))
250: return s;
251:
252: /* get # of lines to affect */
253: if ((s = getregion(®ion)) != TRUE)
254: return (s);
255: first = region.r_linep;
256: last = (first == curwp->w_dotp) ? curwp->w_markp : curwp->w_dotp;
257: for (nline = 1; first != last; nline++)
258: first = lforw(first);
259:
1.2 ! millert 260: /* move to beginning of region */
1.1 deraadt 261: curwp->w_dotp = region.r_linep;
262: curwp->w_doto = region.r_offset;
263:
264: /* for each line, go to beginning and insert the prefix string */
265: while (nline--) {
266: (VOID) gotobol(FFRAND, 1);
267: for (prefix = prefix_string; *prefix; prefix++)
268: (VOID) linsert(1, *prefix);
269: (VOID) forwline(FFRAND, 1);
270: }
271: (VOID) gotobol(FFRAND, 1);
272: return TRUE;
273: }
274:
275: /*
276: * Set prefix string.
277: */
278:
1.2 ! millert 279: /* ARGSUSED */
1.1 deraadt 280: setprefix(f, n)
281: {
1.2 ! millert 282: char buf[PREFIXLENGTH];
! 283: register int s;
1.1 deraadt 284:
285: if (prefix_string[0] == '\0')
1.2 ! millert 286: s = ereply("Prefix string: ", buf, sizeof buf);
1.1 deraadt 287: else
288: s = ereply("Prefix string (default %s): ",
1.2 ! millert 289: buf, sizeof buf, prefix_string);
1.1 deraadt 290: if (s == TRUE)
291: (VOID) strcpy(prefix_string, buf);
1.2 ! millert 292: if ((s == FALSE) && (prefix_string[0] != '\0')) /* CR -- use old one */
1.1 deraadt 293: s = TRUE;
294: return s;
295: }
296: #endif