Blame


1 76193d7c 2003-09-30 devnull #include "sam.h"
2 76193d7c 2003-09-30 devnull
3 76193d7c 2003-09-30 devnull /*
4 76193d7c 2003-09-30 devnull * Structure of Undo list:
5 76193d7c 2003-09-30 devnull * The Undo structure follows any associated data, so the list
6 76193d7c 2003-09-30 devnull * can be read backwards: read the structure, then read whatever
7 76193d7c 2003-09-30 devnull * data is associated (insert string, file name) and precedes it.
8 76193d7c 2003-09-30 devnull * The structure includes the previous value of the modify bit
9 76193d7c 2003-09-30 devnull * and a sequence number; successive Undo structures with the
10 76193d7c 2003-09-30 devnull * same sequence number represent simultaneous changes.
11 76193d7c 2003-09-30 devnull */
12 76193d7c 2003-09-30 devnull
13 76193d7c 2003-09-30 devnull typedef struct Undo Undo;
14 76193d7c 2003-09-30 devnull typedef struct Merge Merge;
15 76193d7c 2003-09-30 devnull
16 76193d7c 2003-09-30 devnull struct Undo
17 76193d7c 2003-09-30 devnull {
18 76193d7c 2003-09-30 devnull short type; /* Delete, Insert, Filename, Dot, Mark */
19 76193d7c 2003-09-30 devnull short mod; /* modify bit */
20 76193d7c 2003-09-30 devnull uint seq; /* sequence number */
21 76193d7c 2003-09-30 devnull uint p0; /* location of change (unused in f) */
22 76193d7c 2003-09-30 devnull uint n; /* # runes in string or file name */
23 76193d7c 2003-09-30 devnull };
24 76193d7c 2003-09-30 devnull
25 76193d7c 2003-09-30 devnull struct Merge
26 76193d7c 2003-09-30 devnull {
27 76193d7c 2003-09-30 devnull File *f;
28 76193d7c 2003-09-30 devnull uint seq; /* of logged change */
29 76193d7c 2003-09-30 devnull uint p0; /* location of change (unused in f) */
30 76193d7c 2003-09-30 devnull uint n; /* # runes to delete */
31 76193d7c 2003-09-30 devnull uint nbuf; /* # runes to insert */
32 76193d7c 2003-09-30 devnull Rune buf[RBUFSIZE];
33 76193d7c 2003-09-30 devnull };
34 76193d7c 2003-09-30 devnull
35 76193d7c 2003-09-30 devnull enum
36 76193d7c 2003-09-30 devnull {
37 76193d7c 2003-09-30 devnull Maxmerge = 50,
38 76193d7c 2003-09-30 devnull Undosize = sizeof(Undo)/sizeof(Rune),
39 76193d7c 2003-09-30 devnull };
40 76193d7c 2003-09-30 devnull
41 76193d7c 2003-09-30 devnull static Merge merge;
42 76193d7c 2003-09-30 devnull
43 76193d7c 2003-09-30 devnull File*
44 76193d7c 2003-09-30 devnull fileopen(void)
45 76193d7c 2003-09-30 devnull {
46 76193d7c 2003-09-30 devnull File *f;
47 76193d7c 2003-09-30 devnull
48 76193d7c 2003-09-30 devnull f = emalloc(sizeof(File));
49 76193d7c 2003-09-30 devnull f->dot.f = f;
50 76193d7c 2003-09-30 devnull f->ndot.f = f;
51 76193d7c 2003-09-30 devnull f->seq = 0;
52 76193d7c 2003-09-30 devnull f->mod = FALSE;
53 76193d7c 2003-09-30 devnull f->unread = TRUE;
54 76193d7c 2003-09-30 devnull Strinit0(&f->name);
55 76193d7c 2003-09-30 devnull return f;
56 76193d7c 2003-09-30 devnull }
57 76193d7c 2003-09-30 devnull
58 76193d7c 2003-09-30 devnull int
59 76193d7c 2003-09-30 devnull fileisdirty(File *f)
60 76193d7c 2003-09-30 devnull {
61 76193d7c 2003-09-30 devnull return f->seq != f->cleanseq;
62 76193d7c 2003-09-30 devnull }
63 76193d7c 2003-09-30 devnull
64 76193d7c 2003-09-30 devnull static void
65 76193d7c 2003-09-30 devnull wrinsert(Buffer *delta, int seq, int mod, uint p0, Rune *s, uint ns)
66 76193d7c 2003-09-30 devnull {
67 76193d7c 2003-09-30 devnull Undo u;
68 76193d7c 2003-09-30 devnull
69 76193d7c 2003-09-30 devnull u.type = Insert;
70 76193d7c 2003-09-30 devnull u.mod = mod;
71 76193d7c 2003-09-30 devnull u.seq = seq;
72 76193d7c 2003-09-30 devnull u.p0 = p0;
73 76193d7c 2003-09-30 devnull u.n = ns;
74 76193d7c 2003-09-30 devnull bufinsert(delta, delta->nc, s, ns);
75 76193d7c 2003-09-30 devnull bufinsert(delta, delta->nc, (Rune*)&u, Undosize);
76 76193d7c 2003-09-30 devnull }
77 76193d7c 2003-09-30 devnull
78 76193d7c 2003-09-30 devnull static void
79 76193d7c 2003-09-30 devnull wrdelete(Buffer *delta, int seq, int mod, uint p0, uint p1)
80 76193d7c 2003-09-30 devnull {
81 76193d7c 2003-09-30 devnull Undo u;
82 76193d7c 2003-09-30 devnull
83 76193d7c 2003-09-30 devnull u.type = Delete;
84 76193d7c 2003-09-30 devnull u.mod = mod;
85 76193d7c 2003-09-30 devnull u.seq = seq;
86 76193d7c 2003-09-30 devnull u.p0 = p0;
87 76193d7c 2003-09-30 devnull u.n = p1 - p0;
88 76193d7c 2003-09-30 devnull bufinsert(delta, delta->nc, (Rune*)&u, Undosize);
89 76193d7c 2003-09-30 devnull }
90 76193d7c 2003-09-30 devnull
91 76193d7c 2003-09-30 devnull void
92 76193d7c 2003-09-30 devnull flushmerge(void)
93 76193d7c 2003-09-30 devnull {
94 76193d7c 2003-09-30 devnull File *f;
95 76193d7c 2003-09-30 devnull
96 76193d7c 2003-09-30 devnull f = merge.f;
97 76193d7c 2003-09-30 devnull if(f == nil)
98 76193d7c 2003-09-30 devnull return;
99 76193d7c 2003-09-30 devnull if(merge.seq != f->seq)
100 76193d7c 2003-09-30 devnull panic("flushmerge seq mismatch");
101 76193d7c 2003-09-30 devnull if(merge.n != 0)
102 76193d7c 2003-09-30 devnull wrdelete(&f->epsilon, f->seq, TRUE, merge.p0, merge.p0+merge.n);
103 76193d7c 2003-09-30 devnull if(merge.nbuf != 0)
104 76193d7c 2003-09-30 devnull wrinsert(&f->epsilon, f->seq, TRUE, merge.p0+merge.n, merge.buf, merge.nbuf);
105 76193d7c 2003-09-30 devnull merge.f = nil;
106 76193d7c 2003-09-30 devnull merge.n = 0;
107 76193d7c 2003-09-30 devnull merge.nbuf = 0;
108 76193d7c 2003-09-30 devnull }
109 76193d7c 2003-09-30 devnull
110 76193d7c 2003-09-30 devnull void
111 76193d7c 2003-09-30 devnull mergeextend(File *f, uint p0)
112 76193d7c 2003-09-30 devnull {
113 76193d7c 2003-09-30 devnull uint mp0n;
114 76193d7c 2003-09-30 devnull
115 76193d7c 2003-09-30 devnull mp0n = merge.p0+merge.n;
116 76193d7c 2003-09-30 devnull if(mp0n != p0){
117 522b0689 2003-09-30 devnull bufread(&f->b, mp0n, merge.buf+merge.nbuf, p0-mp0n);
118 76193d7c 2003-09-30 devnull merge.nbuf += p0-mp0n;
119 76193d7c 2003-09-30 devnull merge.n = p0-merge.p0;
120 76193d7c 2003-09-30 devnull }
121 76193d7c 2003-09-30 devnull }
122 76193d7c 2003-09-30 devnull
123 76193d7c 2003-09-30 devnull /*
124 76193d7c 2003-09-30 devnull * like fileundelete, but get the data from arguments
125 76193d7c 2003-09-30 devnull */
126 76193d7c 2003-09-30 devnull void
127 76193d7c 2003-09-30 devnull loginsert(File *f, uint p0, Rune *s, uint ns)
128 76193d7c 2003-09-30 devnull {
129 76193d7c 2003-09-30 devnull if(f->rescuing)
130 76193d7c 2003-09-30 devnull return;
131 76193d7c 2003-09-30 devnull if(ns == 0)
132 76193d7c 2003-09-30 devnull return;
133 76193d7c 2003-09-30 devnull if(ns<0 || ns>STRSIZE)
134 76193d7c 2003-09-30 devnull panic("loginsert");
135 76193d7c 2003-09-30 devnull if(f->seq < seq)
136 76193d7c 2003-09-30 devnull filemark(f);
137 76193d7c 2003-09-30 devnull if(p0 < f->hiposn)
138 76193d7c 2003-09-30 devnull error(Esequence);
139 76193d7c 2003-09-30 devnull
140 76193d7c 2003-09-30 devnull if(merge.f != f
141 76193d7c 2003-09-30 devnull || p0-(merge.p0+merge.n)>Maxmerge /* too far */
142 76193d7c 2003-09-30 devnull || merge.nbuf+((p0+ns)-(merge.p0+merge.n))>RBUFSIZE) /* too long */
143 76193d7c 2003-09-30 devnull flushmerge();
144 76193d7c 2003-09-30 devnull
145 76193d7c 2003-09-30 devnull if(ns>=RBUFSIZE){
146 76193d7c 2003-09-30 devnull if(!(merge.n == 0 && merge.nbuf == 0 && merge.f == nil))
147 76193d7c 2003-09-30 devnull panic("loginsert bad merge state");
148 76193d7c 2003-09-30 devnull wrinsert(&f->epsilon, f->seq, TRUE, p0, s, ns);
149 76193d7c 2003-09-30 devnull }else{
150 76193d7c 2003-09-30 devnull if(merge.f != f){
151 76193d7c 2003-09-30 devnull merge.f = f;
152 76193d7c 2003-09-30 devnull merge.p0 = p0;
153 76193d7c 2003-09-30 devnull merge.seq = f->seq;
154 76193d7c 2003-09-30 devnull }
155 76193d7c 2003-09-30 devnull mergeextend(f, p0);
156 76193d7c 2003-09-30 devnull
157 76193d7c 2003-09-30 devnull /* append string to merge */
158 76193d7c 2003-09-30 devnull runemove(merge.buf+merge.nbuf, s, ns);
159 76193d7c 2003-09-30 devnull merge.nbuf += ns;
160 76193d7c 2003-09-30 devnull }
161 76193d7c 2003-09-30 devnull
162 76193d7c 2003-09-30 devnull f->hiposn = p0;
163 76193d7c 2003-09-30 devnull if(!f->unread && !f->mod)
164 76193d7c 2003-09-30 devnull state(f, Dirty);
165 76193d7c 2003-09-30 devnull }
166 76193d7c 2003-09-30 devnull
167 76193d7c 2003-09-30 devnull void
168 76193d7c 2003-09-30 devnull logdelete(File *f, uint p0, uint p1)
169 76193d7c 2003-09-30 devnull {
170 76193d7c 2003-09-30 devnull if(f->rescuing)
171 76193d7c 2003-09-30 devnull return;
172 76193d7c 2003-09-30 devnull if(p0 == p1)
173 76193d7c 2003-09-30 devnull return;
174 76193d7c 2003-09-30 devnull if(f->seq < seq)
175 76193d7c 2003-09-30 devnull filemark(f);
176 76193d7c 2003-09-30 devnull if(p0 < f->hiposn)
177 76193d7c 2003-09-30 devnull error(Esequence);
178 76193d7c 2003-09-30 devnull
179 76193d7c 2003-09-30 devnull if(merge.f != f
180 76193d7c 2003-09-30 devnull || p0-(merge.p0+merge.n)>Maxmerge /* too far */
181 76193d7c 2003-09-30 devnull || merge.nbuf+(p0-(merge.p0+merge.n))>RBUFSIZE){ /* too long */
182 76193d7c 2003-09-30 devnull flushmerge();
183 76193d7c 2003-09-30 devnull merge.f = f;
184 76193d7c 2003-09-30 devnull merge.p0 = p0;
185 76193d7c 2003-09-30 devnull merge.seq = f->seq;
186 76193d7c 2003-09-30 devnull }
187 76193d7c 2003-09-30 devnull
188 76193d7c 2003-09-30 devnull mergeextend(f, p0);
189 76193d7c 2003-09-30 devnull
190 76193d7c 2003-09-30 devnull /* add to deletion */
191 76193d7c 2003-09-30 devnull merge.n = p1-merge.p0;
192 76193d7c 2003-09-30 devnull
193 76193d7c 2003-09-30 devnull f->hiposn = p1;
194 76193d7c 2003-09-30 devnull if(!f->unread && !f->mod)
195 76193d7c 2003-09-30 devnull state(f, Dirty);
196 76193d7c 2003-09-30 devnull }
197 76193d7c 2003-09-30 devnull
198 76193d7c 2003-09-30 devnull /*
199 76193d7c 2003-09-30 devnull * like fileunsetname, but get the data from arguments
200 76193d7c 2003-09-30 devnull */
201 76193d7c 2003-09-30 devnull void
202 76193d7c 2003-09-30 devnull logsetname(File *f, String *s)
203 76193d7c 2003-09-30 devnull {
204 76193d7c 2003-09-30 devnull Undo u;
205 76193d7c 2003-09-30 devnull Buffer *delta;
206 76193d7c 2003-09-30 devnull
207 76193d7c 2003-09-30 devnull if(f->rescuing)
208 76193d7c 2003-09-30 devnull return;
209 76193d7c 2003-09-30 devnull
210 76193d7c 2003-09-30 devnull if(f->unread){ /* This is setting initial file name */
211 76193d7c 2003-09-30 devnull filesetname(f, s);
212 76193d7c 2003-09-30 devnull return;
213 76193d7c 2003-09-30 devnull }
214 76193d7c 2003-09-30 devnull
215 76193d7c 2003-09-30 devnull if(f->seq < seq)
216 76193d7c 2003-09-30 devnull filemark(f);
217 76193d7c 2003-09-30 devnull
218 76193d7c 2003-09-30 devnull /* undo a file name change by restoring old name */
219 76193d7c 2003-09-30 devnull delta = &f->epsilon;
220 76193d7c 2003-09-30 devnull u.type = Filename;
221 76193d7c 2003-09-30 devnull u.mod = TRUE;
222 76193d7c 2003-09-30 devnull u.seq = f->seq;
223 76193d7c 2003-09-30 devnull u.p0 = 0; /* unused */
224 76193d7c 2003-09-30 devnull u.n = s->n;
225 76193d7c 2003-09-30 devnull if(s->n)
226 76193d7c 2003-09-30 devnull bufinsert(delta, delta->nc, s->s, s->n);
227 76193d7c 2003-09-30 devnull bufinsert(delta, delta->nc, (Rune*)&u, Undosize);
228 76193d7c 2003-09-30 devnull if(!f->unread && !f->mod)
229 76193d7c 2003-09-30 devnull state(f, Dirty);
230 76193d7c 2003-09-30 devnull }
231 76193d7c 2003-09-30 devnull
232 76193d7c 2003-09-30 devnull #ifdef NOTEXT
233 76193d7c 2003-09-30 devnull File*
234 76193d7c 2003-09-30 devnull fileaddtext(File *f, Text *t)
235 76193d7c 2003-09-30 devnull {
236 76193d7c 2003-09-30 devnull if(f == nil){
237 76193d7c 2003-09-30 devnull f = emalloc(sizeof(File));
238 76193d7c 2003-09-30 devnull f->unread = TRUE;
239 76193d7c 2003-09-30 devnull }
240 76193d7c 2003-09-30 devnull f->text = realloc(f->text, (f->ntext+1)*sizeof(Text*));
241 76193d7c 2003-09-30 devnull f->text[f->ntext++] = t;
242 76193d7c 2003-09-30 devnull f->curtext = t;
243 76193d7c 2003-09-30 devnull return f;
244 76193d7c 2003-09-30 devnull }
245 76193d7c 2003-09-30 devnull
246 76193d7c 2003-09-30 devnull void
247 76193d7c 2003-09-30 devnull filedeltext(File *f, Text *t)
248 76193d7c 2003-09-30 devnull {
249 76193d7c 2003-09-30 devnull int i;
250 76193d7c 2003-09-30 devnull
251 76193d7c 2003-09-30 devnull for(i=0; i<f->ntext; i++)
252 76193d7c 2003-09-30 devnull if(f->text[i] == t)
253 76193d7c 2003-09-30 devnull goto Found;
254 76193d7c 2003-09-30 devnull panic("can't find text in filedeltext");
255 76193d7c 2003-09-30 devnull
256 76193d7c 2003-09-30 devnull Found:
257 76193d7c 2003-09-30 devnull f->ntext--;
258 76193d7c 2003-09-30 devnull if(f->ntext == 0){
259 76193d7c 2003-09-30 devnull fileclose(f);
260 76193d7c 2003-09-30 devnull return;
261 76193d7c 2003-09-30 devnull }
262 76193d7c 2003-09-30 devnull memmove(f->text+i, f->text+i+1, (f->ntext-i)*sizeof(Text*));
263 76193d7c 2003-09-30 devnull if(f->curtext == t)
264 76193d7c 2003-09-30 devnull f->curtext = f->text[0];
265 76193d7c 2003-09-30 devnull }
266 76193d7c 2003-09-30 devnull #endif
267 76193d7c 2003-09-30 devnull
268 76193d7c 2003-09-30 devnull void
269 76193d7c 2003-09-30 devnull fileinsert(File *f, uint p0, Rune *s, uint ns)
270 76193d7c 2003-09-30 devnull {
271 522b0689 2003-09-30 devnull if(p0 > f->b.nc)
272 76193d7c 2003-09-30 devnull panic("internal error: fileinsert");
273 76193d7c 2003-09-30 devnull if(f->seq > 0)
274 76193d7c 2003-09-30 devnull fileuninsert(f, &f->delta, p0, ns);
275 522b0689 2003-09-30 devnull bufinsert(&f->b, p0, s, ns);
276 76193d7c 2003-09-30 devnull if(ns)
277 76193d7c 2003-09-30 devnull f->mod = TRUE;
278 76193d7c 2003-09-30 devnull }
279 76193d7c 2003-09-30 devnull
280 76193d7c 2003-09-30 devnull void
281 76193d7c 2003-09-30 devnull fileuninsert(File *f, Buffer *delta, uint p0, uint ns)
282 76193d7c 2003-09-30 devnull {
283 76193d7c 2003-09-30 devnull Undo u;
284 76193d7c 2003-09-30 devnull
285 76193d7c 2003-09-30 devnull /* undo an insertion by deleting */
286 76193d7c 2003-09-30 devnull u.type = Delete;
287 76193d7c 2003-09-30 devnull u.mod = f->mod;
288 76193d7c 2003-09-30 devnull u.seq = f->seq;
289 76193d7c 2003-09-30 devnull u.p0 = p0;
290 76193d7c 2003-09-30 devnull u.n = ns;
291 76193d7c 2003-09-30 devnull bufinsert(delta, delta->nc, (Rune*)&u, Undosize);
292 76193d7c 2003-09-30 devnull }
293 76193d7c 2003-09-30 devnull
294 76193d7c 2003-09-30 devnull void
295 76193d7c 2003-09-30 devnull filedelete(File *f, uint p0, uint p1)
296 76193d7c 2003-09-30 devnull {
297 522b0689 2003-09-30 devnull if(!(p0<=p1 && p0<=f->b.nc && p1<=f->b.nc))
298 76193d7c 2003-09-30 devnull panic("internal error: filedelete");
299 76193d7c 2003-09-30 devnull if(f->seq > 0)
300 76193d7c 2003-09-30 devnull fileundelete(f, &f->delta, p0, p1);
301 522b0689 2003-09-30 devnull bufdelete(&f->b, p0, p1);
302 76193d7c 2003-09-30 devnull if(p1 > p0)
303 76193d7c 2003-09-30 devnull f->mod = TRUE;
304 76193d7c 2003-09-30 devnull }
305 76193d7c 2003-09-30 devnull
306 76193d7c 2003-09-30 devnull void
307 76193d7c 2003-09-30 devnull fileundelete(File *f, Buffer *delta, uint p0, uint p1)
308 76193d7c 2003-09-30 devnull {
309 76193d7c 2003-09-30 devnull Undo u;
310 76193d7c 2003-09-30 devnull Rune *buf;
311 76193d7c 2003-09-30 devnull uint i, n;
312 76193d7c 2003-09-30 devnull
313 76193d7c 2003-09-30 devnull /* undo a deletion by inserting */
314 76193d7c 2003-09-30 devnull u.type = Insert;
315 76193d7c 2003-09-30 devnull u.mod = f->mod;
316 76193d7c 2003-09-30 devnull u.seq = f->seq;
317 76193d7c 2003-09-30 devnull u.p0 = p0;
318 76193d7c 2003-09-30 devnull u.n = p1-p0;
319 76193d7c 2003-09-30 devnull buf = fbufalloc();
320 76193d7c 2003-09-30 devnull for(i=p0; i<p1; i+=n){
321 76193d7c 2003-09-30 devnull n = p1 - i;
322 76193d7c 2003-09-30 devnull if(n > RBUFSIZE)
323 76193d7c 2003-09-30 devnull n = RBUFSIZE;
324 522b0689 2003-09-30 devnull bufread(&f->b, i, buf, n);
325 76193d7c 2003-09-30 devnull bufinsert(delta, delta->nc, buf, n);
326 76193d7c 2003-09-30 devnull }
327 76193d7c 2003-09-30 devnull fbuffree(buf);
328 76193d7c 2003-09-30 devnull bufinsert(delta, delta->nc, (Rune*)&u, Undosize);
329 76193d7c 2003-09-30 devnull
330 76193d7c 2003-09-30 devnull }
331 76193d7c 2003-09-30 devnull
332 76193d7c 2003-09-30 devnull int
333 76193d7c 2003-09-30 devnull filereadc(File *f, uint q)
334 76193d7c 2003-09-30 devnull {
335 76193d7c 2003-09-30 devnull Rune r;
336 76193d7c 2003-09-30 devnull
337 522b0689 2003-09-30 devnull if(q >= f->b.nc)
338 76193d7c 2003-09-30 devnull return -1;
339 522b0689 2003-09-30 devnull bufread(&f->b, q, &r, 1);
340 76193d7c 2003-09-30 devnull return r;
341 76193d7c 2003-09-30 devnull }
342 76193d7c 2003-09-30 devnull
343 76193d7c 2003-09-30 devnull void
344 76193d7c 2003-09-30 devnull filesetname(File *f, String *s)
345 76193d7c 2003-09-30 devnull {
346 76193d7c 2003-09-30 devnull if(!f->unread) /* This is setting initial file name */
347 76193d7c 2003-09-30 devnull fileunsetname(f, &f->delta);
348 76193d7c 2003-09-30 devnull Strduplstr(&f->name, s);
349 76193d7c 2003-09-30 devnull sortname(f);
350 76193d7c 2003-09-30 devnull f->unread = TRUE;
351 76193d7c 2003-09-30 devnull }
352 76193d7c 2003-09-30 devnull
353 76193d7c 2003-09-30 devnull void
354 76193d7c 2003-09-30 devnull fileunsetname(File *f, Buffer *delta)
355 76193d7c 2003-09-30 devnull {
356 76193d7c 2003-09-30 devnull String s;
357 76193d7c 2003-09-30 devnull Undo u;
358 76193d7c 2003-09-30 devnull
359 76193d7c 2003-09-30 devnull /* undo a file name change by restoring old name */
360 76193d7c 2003-09-30 devnull u.type = Filename;
361 76193d7c 2003-09-30 devnull u.mod = f->mod;
362 76193d7c 2003-09-30 devnull u.seq = f->seq;
363 76193d7c 2003-09-30 devnull u.p0 = 0; /* unused */
364 76193d7c 2003-09-30 devnull Strinit(&s);
365 76193d7c 2003-09-30 devnull Strduplstr(&s, &f->name);
366 76193d7c 2003-09-30 devnull fullname(&s);
367 76193d7c 2003-09-30 devnull u.n = s.n;
368 76193d7c 2003-09-30 devnull if(s.n)
369 76193d7c 2003-09-30 devnull bufinsert(delta, delta->nc, s.s, s.n);
370 76193d7c 2003-09-30 devnull bufinsert(delta, delta->nc, (Rune*)&u, Undosize);
371 76193d7c 2003-09-30 devnull Strclose(&s);
372 76193d7c 2003-09-30 devnull }
373 76193d7c 2003-09-30 devnull
374 76193d7c 2003-09-30 devnull void
375 76193d7c 2003-09-30 devnull fileunsetdot(File *f, Buffer *delta, Range dot)
376 76193d7c 2003-09-30 devnull {
377 76193d7c 2003-09-30 devnull Undo u;
378 76193d7c 2003-09-30 devnull
379 76193d7c 2003-09-30 devnull u.type = Dot;
380 76193d7c 2003-09-30 devnull u.mod = f->mod;
381 76193d7c 2003-09-30 devnull u.seq = f->seq;
382 76193d7c 2003-09-30 devnull u.p0 = dot.p1;
383 76193d7c 2003-09-30 devnull u.n = dot.p2 - dot.p1;
384 76193d7c 2003-09-30 devnull bufinsert(delta, delta->nc, (Rune*)&u, Undosize);
385 76193d7c 2003-09-30 devnull }
386 76193d7c 2003-09-30 devnull
387 76193d7c 2003-09-30 devnull void
388 76193d7c 2003-09-30 devnull fileunsetmark(File *f, Buffer *delta, Range mark)
389 76193d7c 2003-09-30 devnull {
390 76193d7c 2003-09-30 devnull Undo u;
391 76193d7c 2003-09-30 devnull
392 76193d7c 2003-09-30 devnull u.type = Mark;
393 76193d7c 2003-09-30 devnull u.mod = f->mod;
394 76193d7c 2003-09-30 devnull u.seq = f->seq;
395 76193d7c 2003-09-30 devnull u.p0 = mark.p1;
396 76193d7c 2003-09-30 devnull u.n = mark.p2 - mark.p1;
397 76193d7c 2003-09-30 devnull bufinsert(delta, delta->nc, (Rune*)&u, Undosize);
398 76193d7c 2003-09-30 devnull }
399 76193d7c 2003-09-30 devnull
400 76193d7c 2003-09-30 devnull uint
401 76193d7c 2003-09-30 devnull fileload(File *f, uint p0, int fd, int *nulls)
402 76193d7c 2003-09-30 devnull {
403 76193d7c 2003-09-30 devnull if(f->seq > 0)
404 76193d7c 2003-09-30 devnull panic("undo in file.load unimplemented");
405 522b0689 2003-09-30 devnull return bufload(&f->b, p0, fd, nulls);
406 76193d7c 2003-09-30 devnull }
407 76193d7c 2003-09-30 devnull
408 76193d7c 2003-09-30 devnull int
409 76193d7c 2003-09-30 devnull fileupdate(File *f, int notrans, int toterm)
410 76193d7c 2003-09-30 devnull {
411 76193d7c 2003-09-30 devnull uint p1, p2;
412 76193d7c 2003-09-30 devnull int mod;
413 76193d7c 2003-09-30 devnull
414 76193d7c 2003-09-30 devnull if(f->rescuing)
415 76193d7c 2003-09-30 devnull return FALSE;
416 76193d7c 2003-09-30 devnull
417 76193d7c 2003-09-30 devnull flushmerge();
418 76193d7c 2003-09-30 devnull
419 76193d7c 2003-09-30 devnull /*
420 76193d7c 2003-09-30 devnull * fix the modification bit
421 76193d7c 2003-09-30 devnull * subtle point: don't save it away in the log.
422 76193d7c 2003-09-30 devnull *
423 76193d7c 2003-09-30 devnull * if another change is made, the correct f->mod
424 76193d7c 2003-09-30 devnull * state is saved in the undo log by filemark
425 76193d7c 2003-09-30 devnull * when setting the dot and mark.
426 76193d7c 2003-09-30 devnull *
427 76193d7c 2003-09-30 devnull * if the change is undone, the correct state is
428 76193d7c 2003-09-30 devnull * saved from f in the fileun... routines.
429 76193d7c 2003-09-30 devnull */
430 76193d7c 2003-09-30 devnull mod = f->mod;
431 76193d7c 2003-09-30 devnull f->mod = f->prevmod;
432 76193d7c 2003-09-30 devnull if(f == cmd)
433 76193d7c 2003-09-30 devnull notrans = TRUE;
434 76193d7c 2003-09-30 devnull else{
435 76193d7c 2003-09-30 devnull fileunsetdot(f, &f->delta, f->prevdot);
436 76193d7c 2003-09-30 devnull fileunsetmark(f, &f->delta, f->prevmark);
437 76193d7c 2003-09-30 devnull }
438 76193d7c 2003-09-30 devnull f->dot = f->ndot;
439 76193d7c 2003-09-30 devnull fileundo(f, FALSE, !notrans, &p1, &p2, toterm);
440 76193d7c 2003-09-30 devnull f->mod = mod;
441 76193d7c 2003-09-30 devnull
442 76193d7c 2003-09-30 devnull if(f->delta.nc == 0)
443 76193d7c 2003-09-30 devnull f->seq = 0;
444 76193d7c 2003-09-30 devnull
445 76193d7c 2003-09-30 devnull if(f == cmd)
446 76193d7c 2003-09-30 devnull return FALSE;
447 76193d7c 2003-09-30 devnull
448 76193d7c 2003-09-30 devnull if(f->mod){
449 76193d7c 2003-09-30 devnull f->closeok = 0;
450 76193d7c 2003-09-30 devnull quitok = 0;
451 76193d7c 2003-09-30 devnull }else
452 76193d7c 2003-09-30 devnull f->closeok = 1;
453 76193d7c 2003-09-30 devnull return TRUE;
454 76193d7c 2003-09-30 devnull }
455 76193d7c 2003-09-30 devnull
456 76193d7c 2003-09-30 devnull long
457 76193d7c 2003-09-30 devnull prevseq(Buffer *b)
458 76193d7c 2003-09-30 devnull {
459 76193d7c 2003-09-30 devnull Undo u;
460 76193d7c 2003-09-30 devnull uint up;
461 76193d7c 2003-09-30 devnull
462 76193d7c 2003-09-30 devnull up = b->nc;
463 76193d7c 2003-09-30 devnull if(up == 0)
464 76193d7c 2003-09-30 devnull return 0;
465 76193d7c 2003-09-30 devnull up -= Undosize;
466 76193d7c 2003-09-30 devnull bufread(b, up, (Rune*)&u, Undosize);
467 76193d7c 2003-09-30 devnull return u.seq;
468 76193d7c 2003-09-30 devnull }
469 76193d7c 2003-09-30 devnull
470 76193d7c 2003-09-30 devnull long
471 76193d7c 2003-09-30 devnull undoseq(File *f, int isundo)
472 76193d7c 2003-09-30 devnull {
473 76193d7c 2003-09-30 devnull if(isundo)
474 76193d7c 2003-09-30 devnull return f->seq;
475 76193d7c 2003-09-30 devnull
476 76193d7c 2003-09-30 devnull return prevseq(&f->epsilon);
477 76193d7c 2003-09-30 devnull }
478 76193d7c 2003-09-30 devnull
479 76193d7c 2003-09-30 devnull void
480 76193d7c 2003-09-30 devnull fileundo(File *f, int isundo, int canredo, uint *q0p, uint *q1p, int flag)
481 76193d7c 2003-09-30 devnull {
482 76193d7c 2003-09-30 devnull Undo u;
483 76193d7c 2003-09-30 devnull Rune *buf;
484 76193d7c 2003-09-30 devnull uint i, n, up;
485 76193d7c 2003-09-30 devnull uint stop;
486 76193d7c 2003-09-30 devnull Buffer *delta, *epsilon;
487 76193d7c 2003-09-30 devnull
488 76193d7c 2003-09-30 devnull if(isundo){
489 76193d7c 2003-09-30 devnull /* undo; reverse delta onto epsilon, seq decreases */
490 76193d7c 2003-09-30 devnull delta = &f->delta;
491 76193d7c 2003-09-30 devnull epsilon = &f->epsilon;
492 76193d7c 2003-09-30 devnull stop = f->seq;
493 76193d7c 2003-09-30 devnull }else{
494 76193d7c 2003-09-30 devnull /* redo; reverse epsilon onto delta, seq increases */
495 76193d7c 2003-09-30 devnull delta = &f->epsilon;
496 76193d7c 2003-09-30 devnull epsilon = &f->delta;
497 76193d7c 2003-09-30 devnull stop = 0; /* don't know yet */
498 76193d7c 2003-09-30 devnull }
499 76193d7c 2003-09-30 devnull
500 76193d7c 2003-09-30 devnull raspstart(f);
501 76193d7c 2003-09-30 devnull while(delta->nc > 0){
502 76193d7c 2003-09-30 devnull up = delta->nc-Undosize;
503 76193d7c 2003-09-30 devnull bufread(delta, up, (Rune*)&u, Undosize);
504 76193d7c 2003-09-30 devnull if(isundo){
505 76193d7c 2003-09-30 devnull if(u.seq < stop){
506 76193d7c 2003-09-30 devnull f->seq = u.seq;
507 76193d7c 2003-09-30 devnull raspdone(f, flag);
508 76193d7c 2003-09-30 devnull return;
509 76193d7c 2003-09-30 devnull }
510 76193d7c 2003-09-30 devnull }else{
511 76193d7c 2003-09-30 devnull if(stop == 0)
512 76193d7c 2003-09-30 devnull stop = u.seq;
513 76193d7c 2003-09-30 devnull if(u.seq > stop){
514 76193d7c 2003-09-30 devnull raspdone(f, flag);
515 76193d7c 2003-09-30 devnull return;
516 76193d7c 2003-09-30 devnull }
517 76193d7c 2003-09-30 devnull }
518 76193d7c 2003-09-30 devnull switch(u.type){
519 76193d7c 2003-09-30 devnull default:
520 76193d7c 2003-09-30 devnull panic("undo unknown u.type");
521 76193d7c 2003-09-30 devnull break;
522 76193d7c 2003-09-30 devnull
523 76193d7c 2003-09-30 devnull case Delete:
524 76193d7c 2003-09-30 devnull f->seq = u.seq;
525 76193d7c 2003-09-30 devnull if(canredo)
526 76193d7c 2003-09-30 devnull fileundelete(f, epsilon, u.p0, u.p0+u.n);
527 76193d7c 2003-09-30 devnull f->mod = u.mod;
528 522b0689 2003-09-30 devnull bufdelete(&f->b, u.p0, u.p0+u.n);
529 76193d7c 2003-09-30 devnull raspdelete(f, u.p0, u.p0+u.n, flag);
530 76193d7c 2003-09-30 devnull *q0p = u.p0;
531 76193d7c 2003-09-30 devnull *q1p = u.p0;
532 76193d7c 2003-09-30 devnull break;
533 76193d7c 2003-09-30 devnull
534 76193d7c 2003-09-30 devnull case Insert:
535 76193d7c 2003-09-30 devnull f->seq = u.seq;
536 76193d7c 2003-09-30 devnull if(canredo)
537 76193d7c 2003-09-30 devnull fileuninsert(f, epsilon, u.p0, u.n);
538 76193d7c 2003-09-30 devnull f->mod = u.mod;
539 76193d7c 2003-09-30 devnull up -= u.n;
540 76193d7c 2003-09-30 devnull buf = fbufalloc();
541 76193d7c 2003-09-30 devnull for(i=0; i<u.n; i+=n){
542 76193d7c 2003-09-30 devnull n = u.n - i;
543 76193d7c 2003-09-30 devnull if(n > RBUFSIZE)
544 76193d7c 2003-09-30 devnull n = RBUFSIZE;
545 76193d7c 2003-09-30 devnull bufread(delta, up+i, buf, n);
546 522b0689 2003-09-30 devnull bufinsert(&f->b, u.p0+i, buf, n);
547 76193d7c 2003-09-30 devnull raspinsert(f, u.p0+i, buf, n, flag);
548 76193d7c 2003-09-30 devnull }
549 76193d7c 2003-09-30 devnull fbuffree(buf);
550 76193d7c 2003-09-30 devnull *q0p = u.p0;
551 76193d7c 2003-09-30 devnull *q1p = u.p0+u.n;
552 76193d7c 2003-09-30 devnull break;
553 76193d7c 2003-09-30 devnull
554 76193d7c 2003-09-30 devnull case Filename:
555 76193d7c 2003-09-30 devnull f->seq = u.seq;
556 76193d7c 2003-09-30 devnull if(canredo)
557 76193d7c 2003-09-30 devnull fileunsetname(f, epsilon);
558 76193d7c 2003-09-30 devnull f->mod = u.mod;
559 76193d7c 2003-09-30 devnull up -= u.n;
560 76193d7c 2003-09-30 devnull
561 76193d7c 2003-09-30 devnull Strinsure(&f->name, u.n+1);
562 76193d7c 2003-09-30 devnull bufread(delta, up, f->name.s, u.n);
563 76193d7c 2003-09-30 devnull f->name.s[u.n] = 0;
564 76193d7c 2003-09-30 devnull f->name.n = u.n;
565 76193d7c 2003-09-30 devnull fixname(&f->name);
566 76193d7c 2003-09-30 devnull sortname(f);
567 76193d7c 2003-09-30 devnull break;
568 76193d7c 2003-09-30 devnull case Dot:
569 76193d7c 2003-09-30 devnull f->seq = u.seq;
570 76193d7c 2003-09-30 devnull if(canredo)
571 76193d7c 2003-09-30 devnull fileunsetdot(f, epsilon, f->dot.r);
572 76193d7c 2003-09-30 devnull f->mod = u.mod;
573 76193d7c 2003-09-30 devnull f->dot.r.p1 = u.p0;
574 76193d7c 2003-09-30 devnull f->dot.r.p2 = u.p0 + u.n;
575 76193d7c 2003-09-30 devnull break;
576 76193d7c 2003-09-30 devnull case Mark:
577 76193d7c 2003-09-30 devnull f->seq = u.seq;
578 76193d7c 2003-09-30 devnull if(canredo)
579 76193d7c 2003-09-30 devnull fileunsetmark(f, epsilon, f->mark);
580 76193d7c 2003-09-30 devnull f->mod = u.mod;
581 76193d7c 2003-09-30 devnull f->mark.p1 = u.p0;
582 76193d7c 2003-09-30 devnull f->mark.p2 = u.p0 + u.n;
583 76193d7c 2003-09-30 devnull break;
584 76193d7c 2003-09-30 devnull }
585 76193d7c 2003-09-30 devnull bufdelete(delta, up, delta->nc);
586 76193d7c 2003-09-30 devnull }
587 76193d7c 2003-09-30 devnull if(isundo)
588 76193d7c 2003-09-30 devnull f->seq = 0;
589 76193d7c 2003-09-30 devnull raspdone(f, flag);
590 76193d7c 2003-09-30 devnull }
591 76193d7c 2003-09-30 devnull
592 76193d7c 2003-09-30 devnull void
593 76193d7c 2003-09-30 devnull filereset(File *f)
594 76193d7c 2003-09-30 devnull {
595 76193d7c 2003-09-30 devnull bufreset(&f->delta);
596 76193d7c 2003-09-30 devnull bufreset(&f->epsilon);
597 76193d7c 2003-09-30 devnull f->seq = 0;
598 76193d7c 2003-09-30 devnull }
599 76193d7c 2003-09-30 devnull
600 76193d7c 2003-09-30 devnull void
601 76193d7c 2003-09-30 devnull fileclose(File *f)
602 76193d7c 2003-09-30 devnull {
603 76193d7c 2003-09-30 devnull Strclose(&f->name);
604 522b0689 2003-09-30 devnull bufclose(&f->b);
605 76193d7c 2003-09-30 devnull bufclose(&f->delta);
606 76193d7c 2003-09-30 devnull bufclose(&f->epsilon);
607 76193d7c 2003-09-30 devnull if(f->rasp)
608 76193d7c 2003-09-30 devnull listfree(f->rasp);
609 76193d7c 2003-09-30 devnull free(f);
610 76193d7c 2003-09-30 devnull }
611 76193d7c 2003-09-30 devnull
612 76193d7c 2003-09-30 devnull void
613 76193d7c 2003-09-30 devnull filemark(File *f)
614 76193d7c 2003-09-30 devnull {
615 76193d7c 2003-09-30 devnull
616 76193d7c 2003-09-30 devnull if(f->unread)
617 76193d7c 2003-09-30 devnull return;
618 76193d7c 2003-09-30 devnull if(f->epsilon.nc)
619 76193d7c 2003-09-30 devnull bufdelete(&f->epsilon, 0, f->epsilon.nc);
620 76193d7c 2003-09-30 devnull
621 76193d7c 2003-09-30 devnull if(f != cmd){
622 76193d7c 2003-09-30 devnull f->prevdot = f->dot.r;
623 76193d7c 2003-09-30 devnull f->prevmark = f->mark;
624 76193d7c 2003-09-30 devnull f->prevseq = f->seq;
625 76193d7c 2003-09-30 devnull f->prevmod = f->mod;
626 76193d7c 2003-09-30 devnull }
627 76193d7c 2003-09-30 devnull
628 76193d7c 2003-09-30 devnull f->ndot = f->dot;
629 76193d7c 2003-09-30 devnull f->seq = seq;
630 76193d7c 2003-09-30 devnull f->hiposn = 0;
631 76193d7c 2003-09-30 devnull }