Introduction
Introduction Statistics Contact Development Disclaimer Help
rasp.c - sam - An updated version of the sam text editor.
git clone git://vernunftzentrum.de/sam.git
Log
Files
Refs
LICENSE
---
rasp.c (5438B)
---
1 /* Copyright (c) 1998 Lucent Technologies - All rights reserved. */
2 #include <u.h>
3 #include <libg.h>
4 #include <frame.h>
5 #include "flayer.h"
6 #include "samterm.h"
7
8 void
9 rinit(Rasp *r)
10 {
11 r->nrunes=0;
12 r->sect=0;
13 }
14
15 void
16 rclear(Rasp *r)
17 {
18 Section *s, *ns;
19
20 for(s=r->sect; s; s=ns){
21 ns = s->next;
22 free(s->text);
23 free(s);
24 }
25 r->sect = 0;
26 }
27
28 Section*
29 rsinsert(Rasp *r, Section *s) /* insert before s */
30 {
31 Section *t;
32 Section *u;
33
34 t = alloc(sizeof(Section));
35 if(r->sect == s){ /* includes empty list case: r->sect==s==0 */
36 r->sect = t;
37 t->next = s;
38 }else{
39 u = r->sect;
40 if(u == 0)
41 panic("rsinsert 1");
42 do{
43 if(u->next == s){
44 t->next = s;
45 u->next = t;
46 goto Return;
47 }
48 u=u->next;
49 }while(u);
50 panic("rsinsert 2");
51 }
52 Return:
53 return t;
54 }
55
56 void
57 rsdelete(Rasp *r, Section *s)
58 {
59 Section *t;
60
61 if(s == 0)
62 panic("rsdelete");
63 if(r->sect == s){
64 r->sect = s->next;
65 goto Free;
66 }
67 for(t=r->sect; t; t=t->next)
68 if(t->next == s){
69 t->next = s->next;
70 Free:
71 if(s->text)
72 free(s->text);
73 free(s);
74 return;
75 }
76 panic("rsdelete 2");
77 }
78
79 void
80 splitsect(Rasp *r, Section *s, int64_t n0)
81 {
82 if(s == 0)
83 panic("splitsect");
84 rsinsert(r, s->next);
85 if(s->text == 0)
86 s->next->text = 0;
87 else{
88 s->next->text = alloc(RUNESIZE*(TBLOCKSIZE+1));
89 Strcpy(s->next->text, s->text+n0);
90 s->text[n0] = 0;
91 }
92 s->next->nrunes = s->nrunes-n0;
93 s->nrunes = n0;
94 }
95
96 Section *
97 findsect(Rasp *r, Section *s, int64_t p, int64_t q) /* find sect conta…
98 {
99 if(s==0 && p!=q)
100 panic("findsect");
101 for(; s && p+s->nrunes<=q; s=s->next)
102 p += s->nrunes;
103 if(p != q){
104 splitsect(r, s, q-p);
105 s = s->next;
106 }
107 return s;
108 }
109
110 void
111 rresize(Rasp *r, int64_t a, int64_t old, int64_t new)
112 {
113 Section *s, *t, *ns;
114
115 s = findsect(r, r->sect, 0L, a);
116 t = findsect(r, s, a, a+old);
117 for(; s!=t; s=ns){
118 ns=s->next;
119 rsdelete(r, s);
120 }
121 /* now insert the new piece before t */
122 if(new > 0){
123 ns=rsinsert(r, t);
124 ns->nrunes=new;
125 ns->text=0;
126 }
127 r->nrunes += new-old;
128 }
129
130 void
131 rdata(Rasp *r, int64_t p0, int64_t p1, wchar_t *cp)
132 {
133 Section *s, *t, *ns;
134
135 s = findsect(r, r->sect, 0L, p0);
136 t = findsect(r, s, p0, p1);
137 for(; s!=t; s=ns){
138 ns=s->next;
139 if(s->text)
140 panic("rdata");
141 rsdelete(r, s);
142 }
143 p1 -= p0;
144 s = rsinsert(r, t);
145 s->text = alloc(RUNESIZE*(TBLOCKSIZE+1));
146 memmove(s->text, cp, RUNESIZE*p1);
147 s->text[p1] = 0;
148 s->nrunes = p1;
149 }
150
151 void
152 rclean(Rasp *r)
153 {
154 Section *s;
155
156 for(s=r->sect; s; s=s->next)
157 while(s->next && (s->text!=0)==(s->next->text!=0)){
158 if(s->text){
159 if(s->nrunes+s->next->nrunes>TBLOCKSIZE)
160 break;
161 Strcpy(s->text+s->nrunes, s->next->text);
162 }
163 s->nrunes += s->next->nrunes;
164 rsdelete(r, s->next);
165 }
166 }
167
168 void
169 Strcpy(wchar_t *to, wchar_t *from)
170 {
171 do; while((*to++ = *from++));
172 }
173
174 wchar_t*
175 rload(Rasp *r, uint64_t p0, uint64_t p1, uint64_t *nrp)
176 {
177 Section *s;
178 int64_t p;
179 int n, nb;
180
181 nb = 0;
182 Strgrow(&scratch, &nscralloc, p1-p0+1);
183 scratch[0] = 0;
184 for(p=0,s=r->sect; s && p+s->nrunes<=p0; s=s->next)
185 p += s->nrunes;
186 while(p<p1 && s){
187 /*
188 * Subtle and important. If we are preparing to handle an 'rdat…
189 * call, it's because we have an 'rresize' hole here, so the
190 * screen doesn't have data for that space anyway (it got cut
191 * first). So pretend it isn't there.
192 */
193 if(s->text){
194 n = s->nrunes-(p0-p);
195 if(n>p1-p0) /* all in this section */
196 n = p1-p0;
197 memmove(scratch+nb, s->text+(p0-p), n*RUNESIZE);
198 nb += n;
199 scratch[nb] = 0;
200 }
201 p += s->nrunes;
202 p0 = p;
203 s = s->next;
204 }
205 if(nrp)
206 *nrp = nb;
207 return scratch;
208 }
209
210 int
211 rmissing(Rasp *r, uint64_t p0, uint64_t p1)
212 {
213 Section *s;
214 int64_t p;
215 int n, nm=0;
216
217 for(p=0,s=r->sect; s && p+s->nrunes<=p0; s=s->next)
218 p += s->nrunes;
219 while(p<p1 && s){
220 if(s->text == 0){
221 n = s->nrunes-(p0-p);
222 if(n > p1-p0) /* all in this section */
223 n = p1-p0;
224 nm += n;
225 }
226 p += s->nrunes;
227 p0 = p;
228 s = s->next;
229 }
230 return nm;
231 }
232
233 int
234 rcontig(Rasp *r, uint64_t p0, uint64_t p1, bool text)
235 {
236 Section *s;
237 int64_t p, n;
238 int np=0;
239
240 for(p=0,s=r->sect; s && p+s->nrunes<=p0; s=s->next)
241 p += s->nrunes;
242 while(p<p1 && s && (text ? (s->text!=0) : (s->text==0))){
243 n = s->nrunes-(p0-p);
244 if(n > p1-p0) /* all in this section */
245 n = p1-p0;
246 np += n;
247 p += s->nrunes;
248 p0 = p;
249 s = s->next;
250 }
251 return np;
252 }
253
254 void
255 Strgrow(wchar_t **s, int64_t *n, int want) /* can always toss the old…
256 {
257 if(*n >= want)
258 return;
259 free(*s);
260 *s = alloc(RUNESIZE*want);
261 *n = want;
262 }
You are viewing proxied material from vernunftzentrum.de. The copyright of proxied material belongs to its original authors. Any comments or complaints in relation to proxied material should be directed to the original authors of the content concerned. Please see the disclaimer for more details.