* S/MIME: Some clients do not transform messages to canonical form when
[alpine.git] / pico / region.c
blobe1e658963b8857323821200feab3310ae2504b81
1 #if !defined(lint) && !defined(DOS)
2 static char rcsid[] = "$Id: region.c 761 2007-10-23 22:35:18Z hubert@u.washington.edu $";
3 #endif
5 /*
6 * ========================================================================
7 * Copyright 2006 University of Washington
9 * Licensed under the Apache License, Version 2.0 (the "License");
10 * you may not use this file except in compliance with the License.
11 * You may obtain a copy of the License at
13 * http://www.apache.org/licenses/LICENSE-2.0
15 * ========================================================================
19 * Program: Region management routines
21 * The routines in this file
22 * deal with the region, that magic space
23 * between "." and mark. Some functions are
24 * commands. Some functions are just for
25 * internal use.
27 #include "headers.h"
30 * Kill the region. Ask "getregion"
31 * to figure out the bounds of the region.
32 * Move "." to the start, and kill the characters.
33 * Bound to "C-W".
35 int
36 killregion(int f, int n)
38 REGION region;
40 if (curbp->b_mode&MDVIEW) /* don't allow this command if */
41 return(rdonly()); /* we are in read only mode */
43 if (getregion(&region, curwp->w_markp, curwp->w_marko) != TRUE){
44 return (killtext(f, n));
45 }else {
46 mlerase();
49 if ((lastflag&CFKILL) == 0) /* This is a kill type */
50 kdelete(); /* command, so do magic */
52 thisflag |= CFKILL; /* kill buffer stuff. */
53 curwp->w_dotp = region.r_linep;
54 curwp->w_doto = region.r_offset;
55 curwp->w_markp = NULL;
56 #ifdef _WINDOWS
57 mswin_allowcopycut(NULL);
58 #endif
60 if(ldelete(region.r_size, kinsert)){
61 if(curwp->w_dotp == curwp->w_linep && curwp->w_dotp == curbp->b_linep){
62 curwp->w_force = 0; /* Center dot. */
63 curwp->w_flag |= WFFORCE;
66 return(TRUE);
69 return (FALSE);
74 * Blast the region without saving . Ask "getregion"
75 * to figure out the bounds of the region.
76 * Move "." to the start, and kill the characters.
77 * Bound to "C-W".
79 int
80 deleteregion(int f, int n)
82 REGION region;
84 if (curbp->b_mode&MDVIEW) /* don't allow this command if */
85 return(rdonly()); /* we are in read only mode */
87 if (getregion(&region, curwp->w_markp, curwp->w_marko) == TRUE){
88 curwp->w_dotp = region.r_linep;
89 curwp->w_doto = region.r_offset;
90 curwp->w_markp = NULL;
91 #ifdef _WINDOWS
92 mswin_allowcopycut(NULL);
93 #endif
94 if(ldelete(region.r_size, NULL)){
95 if(curwp->w_dotp == curwp->w_linep
96 && curwp->w_dotp == curbp->b_linep){
97 curwp->w_force = 0; /* Center dot. */
98 curwp->w_flag |= WFFORCE;
101 return(TRUE);
105 return (FALSE);
110 * Copy all of the characters in the
111 * region to the kill buffer. Don't move dot
112 * at all. This is a bit like a kill region followed
113 * by a yank. Bound to "M-W".
116 copyregion(int f, int n)
118 register LINE *linep;
119 register int loffs;
120 register int s;
121 REGION region;
123 if ((s=getregion(&region, curwp->w_markp, curwp->w_marko)) != TRUE)
124 return (s);
126 if ((lastflag&CFKILL) == 0) /* Kill type command. */
127 kdelete();
129 thisflag |= CFKILL;
130 linep = region.r_linep; /* Current line. */
131 loffs = region.r_offset; /* Current offset. */
132 while (region.r_size--) {
133 if (loffs == llength(linep)) { /* End of line. */
134 if ((s=kinsert('\n')) != TRUE)
135 return (s);
136 linep = lforw(linep);
137 loffs = 0;
138 } else { /* Middle of line. */
139 if ((s=kinsert(lgetc(linep, loffs).c)) != TRUE)
140 return (s);
141 ++loffs;
145 return (TRUE);
150 * Lower case region. Zap all of the upper
151 * case characters in the region to lower case. Use
152 * the region code to set the limits. Scan the buffer,
153 * doing the changes. Call "lchange" to ensure that
154 * redisplay is done in all buffers. Bound to
155 * "C-X C-L".
158 lowerregion(int f, int n)
160 register LINE *linep;
161 register int loffs;
162 register int c;
163 register int s;
164 REGION region;
165 CELL ac;
167 ac.a = 0;
168 if (curbp->b_mode&MDVIEW) /* don't allow this command if */
169 return(rdonly()); /* we are in read only mode */
171 if ((s=getregion(&region, curwp->w_markp, curwp->w_marko)) != TRUE)
172 return (s);
174 lchange(WFHARD);
175 linep = region.r_linep;
176 loffs = region.r_offset;
177 while (region.r_size--) {
178 if (loffs == llength(linep)) {
179 linep = lforw(linep);
180 loffs = 0;
181 } else {
182 c = lgetc(linep, loffs).c;
183 if (c>='A' && c<='Z'){
184 ac.c = c+'a'-'A';
185 lputc(linep, loffs, ac);
187 ++loffs;
191 return (TRUE);
195 * Upper case region. Zap all of the lower
196 * case characters in the region to upper case. Use
197 * the region code to set the limits. Scan the buffer,
198 * doing the changes. Call "lchange" to ensure that
199 * redisplay is done in all buffers. Bound to
200 * "C-X C-L".
203 upperregion(int f, int n)
205 register LINE *linep;
206 register int loffs;
207 register int c;
208 register int s;
209 REGION region;
210 CELL ac;
212 ac.a = 0;
213 if (curbp->b_mode&MDVIEW) /* don't allow this command if */
214 return(rdonly()); /* we are in read only mode */
216 if ((s=getregion(&region, curwp->w_markp, curwp->w_marko)) != TRUE)
217 return (s);
219 lchange(WFHARD);
220 linep = region.r_linep;
221 loffs = region.r_offset;
222 while (region.r_size--) {
223 if (loffs == llength(linep)) {
224 linep = lforw(linep);
225 loffs = 0;
226 } else {
227 c = lgetc(linep, loffs).c;
228 if (c>='a' && c<='z'){
229 ac.c = c - 'a' + 'A';
230 lputc(linep, loffs, ac);
232 ++loffs;
236 return (TRUE);
240 * This routine figures out the
241 * bounds of the region in the current window, and
242 * fills in the fields of the "REGION" structure pointed
243 * to by "rp". Because the dot and mark are usually very
244 * close together, we scan outward from dot looking for
245 * mark. This should save time. Return a standard code.
246 * Callers of this routine should be prepared to get
247 * an "ABORT" status; we might make this have the
248 * conform thing later.
251 getregion(REGION *rp, LINE *markp, int marko)
253 register LINE *flp;
254 register LINE *blp;
255 long fsize;
256 register long bsize;
258 if (markp == NULL) {
259 return (FALSE);
262 if (curwp->w_dotp == markp) {
263 rp->r_linep = curwp->w_dotp;
264 if (curwp->w_doto < marko) {
265 rp->r_offset = curwp->w_doto;
266 rp->r_size = marko - curwp->w_doto;
267 } else {
268 rp->r_offset = marko;
269 rp->r_size = curwp->w_doto - marko;
271 return (TRUE);
274 blp = curwp->w_dotp;
275 bsize = curwp->w_doto;
276 flp = curwp->w_dotp;
277 fsize = llength(flp)-curwp->w_doto+1;
278 while (flp!=curbp->b_linep || lback(blp)!=curbp->b_linep) {
279 if (flp != curbp->b_linep) {
280 flp = lforw(flp);
281 if (flp == markp) {
282 rp->r_linep = curwp->w_dotp;
283 rp->r_offset = curwp->w_doto;
284 rp->r_size = fsize + marko;
285 return (TRUE);
288 fsize += llength(flp) + 1;
291 if (lback(blp) != curbp->b_linep) {
292 blp = lback(blp);
293 bsize += llength(blp)+1;
294 if (blp == markp) {
295 rp->r_linep = blp;
296 rp->r_offset = marko;
297 rp->r_size = bsize - marko;
298 return (TRUE);
303 emlwrite("Bug: lost mark", NULL);
304 return (FALSE);
309 * set the highlight attribute accordingly on all characters in region
312 markregion(int attr)
314 register LINE *linep;
315 register int loffs;
316 register int s;
317 REGION region;
318 CELL ac;
320 if ((s=getregion(&region, curwp->w_markp, curwp->w_marko)) != TRUE)
321 return (s);
323 lchange(WFHARD);
324 linep = region.r_linep;
325 loffs = region.r_offset;
326 while (region.r_size--) {
327 if (loffs == llength(linep)) {
328 linep = lforw(linep);
329 loffs = 0;
330 } else {
331 ac = lgetc(linep, loffs);
332 ac.a = attr;
333 lputc(linep, loffs, ac);
334 ++loffs;
338 return (TRUE);
343 * clear all the attributes of all the characters in the buffer?
344 * this is real dumb. Movement with mark set needs to be smarter!
346 void
347 unmarkbuffer(void)
349 register LINE *linep;
350 register int n;
351 CELL c;
353 linep = curwp->w_linep;
354 while(lforw(linep) != curwp->w_linep){
355 n = llength(linep);
356 for(n=0; n < llength(linep); n++){
357 c = lgetc(linep, n);
358 c.a = 0;
359 lputc(linep, n, c);
362 linep = lforw(linep);