Fix for a crash which happened when a document couldn't be opened.
[AROS-Contrib.git] / fish / microemacs / region.c
blob52eea3726264864c6ccdb73517860c55e50a1d17
1 /*
2 * The routines in this file
3 * deal with the region, that magic space
4 * between "." and mark. Some functions are
5 * commands. Some functions are just for
6 * internal use.
7 */
8 #include <stdio.h>
9 #include "ed.h"
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 * Bound to "C-W".
17 int killregion(f, n)
18 int f;
19 int n;
21 register int s;
22 REGION region;
24 if ((s=getregion(&region)) != TRUE)
25 return (s);
26 if ((lastflag&CFKILL) == 0) /* This is a kill type */
27 kdelete(); /* command, so do magic */
28 thisflag |= CFKILL; /* kill buffer stuff. */
29 curwp->w_dotp = region.r_linep;
30 curwp->w_doto = region.r_offset;
31 return (ldelete(region.r_size, TRUE));
35 * Copy all of the characters in the
36 * region to the kill buffer. Don't move dot
37 * at all. This is a bit like a kill region followed
38 * by a yank. Bound to "M-W".
40 int copyregion(f, n)
41 int f;
42 int n;
44 register LINE *linep;
45 register int loffs;
46 register int s;
47 REGION region;
49 if ((s=getregion(&region)) != TRUE)
50 return (s);
51 if ((lastflag&CFKILL) == 0) /* Kill type command. */
52 kdelete();
53 thisflag |= CFKILL;
54 linep = region.r_linep; /* Current line. */
55 loffs = region.r_offset; /* Current offset. */
56 while (region.r_size--) {
57 if (loffs == llength(linep)) { /* End of line. */
58 if ((s=kinsert('\n')) != TRUE)
59 return (s);
60 linep = lforw(linep);
61 loffs = 0;
62 } else { /* Middle of line. */
63 if ((s=kinsert(lgetc(linep, loffs))) != TRUE)
64 return (s);
65 ++loffs;
68 return (TRUE);
72 * Lower case region. Zap all of the upper
73 * case characters in the region to lower case. Use
74 * the region code to set the limits. Scan the buffer,
75 * doing the changes. Call "lchange" to ensure that
76 * redisplay is done in all buffers. Bound to
77 * "C-X C-L".
79 int lowerregion(f, n)
80 int f;
81 int n;
83 register LINE *linep;
84 register int loffs;
85 register int c;
86 register int s;
87 REGION region;
89 if ((s=getregion(&region)) != TRUE)
90 return (s);
91 lchange(WFHARD);
92 linep = region.r_linep;
93 loffs = region.r_offset;
94 while (region.r_size--) {
95 if (loffs == llength(linep)) {
96 linep = lforw(linep);
97 loffs = 0;
98 } else {
99 c = lgetc(linep, loffs);
100 if (c>='A' && c<='Z')
101 lputc(linep, loffs, c+'a'-'A');
102 ++loffs;
105 return (TRUE);
109 * Upper case region. Zap all of the lower
110 * case characters in the region to upper case. Use
111 * the region code to set the limits. Scan the buffer,
112 * doing the changes. Call "lchange" to ensure that
113 * redisplay is done in all buffers. Bound to
114 * "C-X C-L".
116 int upperregion(f, n)
117 int f;
118 int n;
120 register LINE *linep;
121 register int loffs;
122 register int c;
123 register int s;
124 REGION region;
126 if ((s=getregion(&region)) != TRUE)
127 return (s);
128 lchange(WFHARD);
129 linep = region.r_linep;
130 loffs = region.r_offset;
131 while (region.r_size--) {
132 if (loffs == llength(linep)) {
133 linep = lforw(linep);
134 loffs = 0;
135 } else {
136 c = lgetc(linep, loffs);
137 if (c>='a' && c<='z')
138 lputc(linep, loffs, c-'a'+'A');
139 ++loffs;
142 return (TRUE);
146 * This routine figures out the
147 * bounds of the region in the current window, and
148 * fills in the fields of the "REGION" structure pointed
149 * to by "rp". Because the dot and mark are usually very
150 * close together, we scan outward from dot looking for
151 * mark. This should save time. Return a standard code.
152 * Callers of this routine should be prepared to get
153 * an "ABORT" status; we might make this have the
154 * conform thing later.
156 int getregion(rp)
157 register REGION *rp;
159 register LINE *flp;
160 register LINE *blp;
161 register int fsize;
162 register int bsize;
164 if (curwp->w_markp == NULL) {
165 mlwrite("No mark set in this window");
166 return (FALSE);
168 if (curwp->w_dotp == curwp->w_markp) {
169 rp->r_linep = curwp->w_dotp;
170 if (curwp->w_doto < curwp->w_marko) {
171 rp->r_offset = curwp->w_doto;
172 rp->r_size = curwp->w_marko-curwp->w_doto;
173 } else {
174 rp->r_offset = curwp->w_marko;
175 rp->r_size = curwp->w_doto-curwp->w_marko;
177 return (TRUE);
179 blp = curwp->w_dotp;
180 bsize = curwp->w_doto;
181 flp = curwp->w_dotp;
182 fsize = llength(flp)-curwp->w_doto+1;
183 while (flp!=curbp->b_linep || lback(blp)!=curbp->b_linep) {
184 if (flp != curbp->b_linep) {
185 flp = lforw(flp);
186 if (flp == curwp->w_markp) {
187 rp->r_linep = curwp->w_dotp;
188 rp->r_offset = curwp->w_doto;
189 rp->r_size = fsize+curwp->w_marko;
190 return (TRUE);
192 fsize += llength(flp)+1;
194 if (lback(blp) != curbp->b_linep) {
195 blp = lback(blp);
196 bsize += llength(blp)+1;
197 if (blp == curwp->w_markp) {
198 rp->r_linep = blp;
199 rp->r_offset = curwp->w_marko;
200 rp->r_size = bsize - curwp->w_marko;
201 return (TRUE);
205 mlwrite("Bug: lost mark");
206 return (FALSE);