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 cbeb0b26 2006-04-01 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 0cfb3760 2012-10-21 rsc if(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 846cec9e 2009-12-07 rsc || 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 846cec9e 2009-12-07 rsc || 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 fileuninsert(File *f, Buffer *delta, uint p0, uint ns)
270 76193d7c 2003-09-30 devnull {
271 76193d7c 2003-09-30 devnull Undo u;
272 76193d7c 2003-09-30 devnull
273 76193d7c 2003-09-30 devnull /* undo an insertion by deleting */
274 76193d7c 2003-09-30 devnull u.type = Delete;
275 76193d7c 2003-09-30 devnull u.mod = f->mod;
276 76193d7c 2003-09-30 devnull u.seq = f->seq;
277 76193d7c 2003-09-30 devnull u.p0 = p0;
278 76193d7c 2003-09-30 devnull u.n = ns;
279 76193d7c 2003-09-30 devnull bufinsert(delta, delta->nc, (Rune*)&u, Undosize);
280 76193d7c 2003-09-30 devnull }
281 76193d7c 2003-09-30 devnull
282 76193d7c 2003-09-30 devnull void
283 76193d7c 2003-09-30 devnull fileundelete(File *f, Buffer *delta, uint p0, uint p1)
284 76193d7c 2003-09-30 devnull {
285 76193d7c 2003-09-30 devnull Undo u;
286 76193d7c 2003-09-30 devnull Rune *buf;
287 76193d7c 2003-09-30 devnull uint i, n;
288 76193d7c 2003-09-30 devnull
289 76193d7c 2003-09-30 devnull /* undo a deletion by inserting */
290 76193d7c 2003-09-30 devnull u.type = Insert;
291 76193d7c 2003-09-30 devnull u.mod = f->mod;
292 76193d7c 2003-09-30 devnull u.seq = f->seq;
293 76193d7c 2003-09-30 devnull u.p0 = p0;
294 76193d7c 2003-09-30 devnull u.n = p1-p0;
295 76193d7c 2003-09-30 devnull buf = fbufalloc();
296 76193d7c 2003-09-30 devnull for(i=p0; i<p1; i+=n){
297 76193d7c 2003-09-30 devnull n = p1 - i;
298 76193d7c 2003-09-30 devnull if(n > RBUFSIZE)
299 76193d7c 2003-09-30 devnull n = RBUFSIZE;
300 522b0689 2003-09-30 devnull bufread(&f->b, i, buf, n);
301 76193d7c 2003-09-30 devnull bufinsert(delta, delta->nc, buf, n);
302 76193d7c 2003-09-30 devnull }
303 76193d7c 2003-09-30 devnull fbuffree(buf);
304 76193d7c 2003-09-30 devnull bufinsert(delta, delta->nc, (Rune*)&u, Undosize);
305 76193d7c 2003-09-30 devnull
306 76193d7c 2003-09-30 devnull }
307 76193d7c 2003-09-30 devnull
308 76193d7c 2003-09-30 devnull int
309 76193d7c 2003-09-30 devnull filereadc(File *f, uint q)
310 76193d7c 2003-09-30 devnull {
311 76193d7c 2003-09-30 devnull Rune r;
312 76193d7c 2003-09-30 devnull
313 522b0689 2003-09-30 devnull if(q >= f->b.nc)
314 76193d7c 2003-09-30 devnull return -1;
315 522b0689 2003-09-30 devnull bufread(&f->b, q, &r, 1);
316 76193d7c 2003-09-30 devnull return r;
317 76193d7c 2003-09-30 devnull }
318 76193d7c 2003-09-30 devnull
319 76193d7c 2003-09-30 devnull void
320 76193d7c 2003-09-30 devnull filesetname(File *f, String *s)
321 76193d7c 2003-09-30 devnull {
322 76193d7c 2003-09-30 devnull if(!f->unread) /* This is setting initial file name */
323 76193d7c 2003-09-30 devnull fileunsetname(f, &f->delta);
324 76193d7c 2003-09-30 devnull Strduplstr(&f->name, s);
325 76193d7c 2003-09-30 devnull sortname(f);
326 76193d7c 2003-09-30 devnull f->unread = TRUE;
327 76193d7c 2003-09-30 devnull }
328 76193d7c 2003-09-30 devnull
329 76193d7c 2003-09-30 devnull void
330 76193d7c 2003-09-30 devnull fileunsetname(File *f, Buffer *delta)
331 76193d7c 2003-09-30 devnull {
332 76193d7c 2003-09-30 devnull String s;
333 76193d7c 2003-09-30 devnull Undo u;
334 76193d7c 2003-09-30 devnull
335 76193d7c 2003-09-30 devnull /* undo a file name change by restoring old name */
336 76193d7c 2003-09-30 devnull u.type = Filename;
337 76193d7c 2003-09-30 devnull u.mod = f->mod;
338 76193d7c 2003-09-30 devnull u.seq = f->seq;
339 76193d7c 2003-09-30 devnull u.p0 = 0; /* unused */
340 76193d7c 2003-09-30 devnull Strinit(&s);
341 76193d7c 2003-09-30 devnull Strduplstr(&s, &f->name);
342 76193d7c 2003-09-30 devnull fullname(&s);
343 76193d7c 2003-09-30 devnull u.n = s.n;
344 76193d7c 2003-09-30 devnull if(s.n)
345 76193d7c 2003-09-30 devnull bufinsert(delta, delta->nc, s.s, s.n);
346 76193d7c 2003-09-30 devnull bufinsert(delta, delta->nc, (Rune*)&u, Undosize);
347 76193d7c 2003-09-30 devnull Strclose(&s);
348 76193d7c 2003-09-30 devnull }
349 76193d7c 2003-09-30 devnull
350 76193d7c 2003-09-30 devnull void
351 76193d7c 2003-09-30 devnull fileunsetdot(File *f, Buffer *delta, Range dot)
352 76193d7c 2003-09-30 devnull {
353 76193d7c 2003-09-30 devnull Undo u;
354 76193d7c 2003-09-30 devnull
355 76193d7c 2003-09-30 devnull u.type = Dot;
356 76193d7c 2003-09-30 devnull u.mod = f->mod;
357 76193d7c 2003-09-30 devnull u.seq = f->seq;
358 76193d7c 2003-09-30 devnull u.p0 = dot.p1;
359 76193d7c 2003-09-30 devnull u.n = dot.p2 - dot.p1;
360 76193d7c 2003-09-30 devnull bufinsert(delta, delta->nc, (Rune*)&u, Undosize);
361 76193d7c 2003-09-30 devnull }
362 76193d7c 2003-09-30 devnull
363 76193d7c 2003-09-30 devnull void
364 76193d7c 2003-09-30 devnull fileunsetmark(File *f, Buffer *delta, Range mark)
365 76193d7c 2003-09-30 devnull {
366 76193d7c 2003-09-30 devnull Undo u;
367 76193d7c 2003-09-30 devnull
368 76193d7c 2003-09-30 devnull u.type = Mark;
369 76193d7c 2003-09-30 devnull u.mod = f->mod;
370 76193d7c 2003-09-30 devnull u.seq = f->seq;
371 76193d7c 2003-09-30 devnull u.p0 = mark.p1;
372 76193d7c 2003-09-30 devnull u.n = mark.p2 - mark.p1;
373 76193d7c 2003-09-30 devnull bufinsert(delta, delta->nc, (Rune*)&u, Undosize);
374 76193d7c 2003-09-30 devnull }
375 76193d7c 2003-09-30 devnull
376 76193d7c 2003-09-30 devnull uint
377 76193d7c 2003-09-30 devnull fileload(File *f, uint p0, int fd, int *nulls)
378 76193d7c 2003-09-30 devnull {
379 76193d7c 2003-09-30 devnull if(f->seq > 0)
380 76193d7c 2003-09-30 devnull panic("undo in file.load unimplemented");
381 522b0689 2003-09-30 devnull return bufload(&f->b, p0, fd, nulls);
382 76193d7c 2003-09-30 devnull }
383 76193d7c 2003-09-30 devnull
384 76193d7c 2003-09-30 devnull int
385 76193d7c 2003-09-30 devnull fileupdate(File *f, int notrans, int toterm)
386 76193d7c 2003-09-30 devnull {
387 76193d7c 2003-09-30 devnull uint p1, p2;
388 76193d7c 2003-09-30 devnull int mod;
389 76193d7c 2003-09-30 devnull
390 76193d7c 2003-09-30 devnull if(f->rescuing)
391 76193d7c 2003-09-30 devnull return FALSE;
392 76193d7c 2003-09-30 devnull
393 76193d7c 2003-09-30 devnull flushmerge();
394 76193d7c 2003-09-30 devnull
395 76193d7c 2003-09-30 devnull /*
396 76193d7c 2003-09-30 devnull * fix the modification bit
397 76193d7c 2003-09-30 devnull * subtle point: don't save it away in the log.
398 76193d7c 2003-09-30 devnull *
399 76193d7c 2003-09-30 devnull * if another change is made, the correct f->mod
400 76193d7c 2003-09-30 devnull * state is saved in the undo log by filemark
401 76193d7c 2003-09-30 devnull * when setting the dot and mark.
402 76193d7c 2003-09-30 devnull *
403 76193d7c 2003-09-30 devnull * if the change is undone, the correct state is
404 76193d7c 2003-09-30 devnull * saved from f in the fileun... routines.
405 76193d7c 2003-09-30 devnull */
406 76193d7c 2003-09-30 devnull mod = f->mod;
407 76193d7c 2003-09-30 devnull f->mod = f->prevmod;
408 76193d7c 2003-09-30 devnull if(f == cmd)
409 76193d7c 2003-09-30 devnull notrans = TRUE;
410 76193d7c 2003-09-30 devnull else{
411 76193d7c 2003-09-30 devnull fileunsetdot(f, &f->delta, f->prevdot);
412 76193d7c 2003-09-30 devnull fileunsetmark(f, &f->delta, f->prevmark);
413 76193d7c 2003-09-30 devnull }
414 76193d7c 2003-09-30 devnull f->dot = f->ndot;
415 76193d7c 2003-09-30 devnull fileundo(f, FALSE, !notrans, &p1, &p2, toterm);
416 76193d7c 2003-09-30 devnull f->mod = mod;
417 76193d7c 2003-09-30 devnull
418 76193d7c 2003-09-30 devnull if(f->delta.nc == 0)
419 76193d7c 2003-09-30 devnull f->seq = 0;
420 76193d7c 2003-09-30 devnull
421 76193d7c 2003-09-30 devnull if(f == cmd)
422 76193d7c 2003-09-30 devnull return FALSE;
423 76193d7c 2003-09-30 devnull
424 76193d7c 2003-09-30 devnull if(f->mod){
425 76193d7c 2003-09-30 devnull f->closeok = 0;
426 76193d7c 2003-09-30 devnull quitok = 0;
427 76193d7c 2003-09-30 devnull }else
428 76193d7c 2003-09-30 devnull f->closeok = 1;
429 76193d7c 2003-09-30 devnull return TRUE;
430 76193d7c 2003-09-30 devnull }
431 76193d7c 2003-09-30 devnull
432 76193d7c 2003-09-30 devnull long
433 76193d7c 2003-09-30 devnull prevseq(Buffer *b)
434 76193d7c 2003-09-30 devnull {
435 76193d7c 2003-09-30 devnull Undo u;
436 76193d7c 2003-09-30 devnull uint up;
437 76193d7c 2003-09-30 devnull
438 76193d7c 2003-09-30 devnull up = b->nc;
439 76193d7c 2003-09-30 devnull if(up == 0)
440 76193d7c 2003-09-30 devnull return 0;
441 76193d7c 2003-09-30 devnull up -= Undosize;
442 76193d7c 2003-09-30 devnull bufread(b, up, (Rune*)&u, Undosize);
443 76193d7c 2003-09-30 devnull return u.seq;
444 76193d7c 2003-09-30 devnull }
445 76193d7c 2003-09-30 devnull
446 76193d7c 2003-09-30 devnull long
447 76193d7c 2003-09-30 devnull undoseq(File *f, int isundo)
448 76193d7c 2003-09-30 devnull {
449 76193d7c 2003-09-30 devnull if(isundo)
450 76193d7c 2003-09-30 devnull return f->seq;
451 76193d7c 2003-09-30 devnull
452 76193d7c 2003-09-30 devnull return prevseq(&f->epsilon);
453 76193d7c 2003-09-30 devnull }
454 76193d7c 2003-09-30 devnull
455 76193d7c 2003-09-30 devnull void
456 76193d7c 2003-09-30 devnull fileundo(File *f, int isundo, int canredo, uint *q0p, uint *q1p, int flag)
457 76193d7c 2003-09-30 devnull {
458 76193d7c 2003-09-30 devnull Undo u;
459 76193d7c 2003-09-30 devnull Rune *buf;
460 76193d7c 2003-09-30 devnull uint i, n, up;
461 76193d7c 2003-09-30 devnull uint stop;
462 76193d7c 2003-09-30 devnull Buffer *delta, *epsilon;
463 76193d7c 2003-09-30 devnull
464 76193d7c 2003-09-30 devnull if(isundo){
465 76193d7c 2003-09-30 devnull /* undo; reverse delta onto epsilon, seq decreases */
466 76193d7c 2003-09-30 devnull delta = &f->delta;
467 76193d7c 2003-09-30 devnull epsilon = &f->epsilon;
468 76193d7c 2003-09-30 devnull stop = f->seq;
469 76193d7c 2003-09-30 devnull }else{
470 76193d7c 2003-09-30 devnull /* redo; reverse epsilon onto delta, seq increases */
471 76193d7c 2003-09-30 devnull delta = &f->epsilon;
472 76193d7c 2003-09-30 devnull epsilon = &f->delta;
473 76193d7c 2003-09-30 devnull stop = 0; /* don't know yet */
474 76193d7c 2003-09-30 devnull }
475 76193d7c 2003-09-30 devnull
476 76193d7c 2003-09-30 devnull raspstart(f);
477 76193d7c 2003-09-30 devnull while(delta->nc > 0){
478 78439d25 2007-01-12 devnull /* rasp and buffer are in sync; sync with wire if needed */
479 78439d25 2007-01-12 devnull if(needoutflush())
480 78439d25 2007-01-12 devnull raspflush(f);
481 76193d7c 2003-09-30 devnull up = delta->nc-Undosize;
482 76193d7c 2003-09-30 devnull bufread(delta, up, (Rune*)&u, Undosize);
483 76193d7c 2003-09-30 devnull if(isundo){
484 76193d7c 2003-09-30 devnull if(u.seq < stop){
485 76193d7c 2003-09-30 devnull f->seq = u.seq;
486 76193d7c 2003-09-30 devnull raspdone(f, flag);
487 76193d7c 2003-09-30 devnull return;
488 76193d7c 2003-09-30 devnull }
489 76193d7c 2003-09-30 devnull }else{
490 76193d7c 2003-09-30 devnull if(stop == 0)
491 76193d7c 2003-09-30 devnull stop = u.seq;
492 76193d7c 2003-09-30 devnull if(u.seq > stop){
493 76193d7c 2003-09-30 devnull raspdone(f, flag);
494 76193d7c 2003-09-30 devnull return;
495 76193d7c 2003-09-30 devnull }
496 76193d7c 2003-09-30 devnull }
497 76193d7c 2003-09-30 devnull switch(u.type){
498 76193d7c 2003-09-30 devnull default:
499 76193d7c 2003-09-30 devnull panic("undo unknown u.type");
500 76193d7c 2003-09-30 devnull break;
501 76193d7c 2003-09-30 devnull
502 76193d7c 2003-09-30 devnull case Delete:
503 76193d7c 2003-09-30 devnull f->seq = u.seq;
504 76193d7c 2003-09-30 devnull if(canredo)
505 76193d7c 2003-09-30 devnull fileundelete(f, epsilon, u.p0, u.p0+u.n);
506 76193d7c 2003-09-30 devnull f->mod = u.mod;
507 522b0689 2003-09-30 devnull bufdelete(&f->b, u.p0, u.p0+u.n);
508 76193d7c 2003-09-30 devnull raspdelete(f, u.p0, u.p0+u.n, flag);
509 76193d7c 2003-09-30 devnull *q0p = u.p0;
510 76193d7c 2003-09-30 devnull *q1p = u.p0;
511 76193d7c 2003-09-30 devnull break;
512 76193d7c 2003-09-30 devnull
513 76193d7c 2003-09-30 devnull case Insert:
514 76193d7c 2003-09-30 devnull f->seq = u.seq;
515 76193d7c 2003-09-30 devnull if(canredo)
516 76193d7c 2003-09-30 devnull fileuninsert(f, epsilon, u.p0, u.n);
517 76193d7c 2003-09-30 devnull f->mod = u.mod;
518 76193d7c 2003-09-30 devnull up -= u.n;
519 76193d7c 2003-09-30 devnull buf = fbufalloc();
520 76193d7c 2003-09-30 devnull for(i=0; i<u.n; i+=n){
521 76193d7c 2003-09-30 devnull n = u.n - i;
522 76193d7c 2003-09-30 devnull if(n > RBUFSIZE)
523 76193d7c 2003-09-30 devnull n = RBUFSIZE;
524 76193d7c 2003-09-30 devnull bufread(delta, up+i, buf, n);
525 522b0689 2003-09-30 devnull bufinsert(&f->b, u.p0+i, buf, n);
526 76193d7c 2003-09-30 devnull raspinsert(f, u.p0+i, buf, n, flag);
527 76193d7c 2003-09-30 devnull }
528 76193d7c 2003-09-30 devnull fbuffree(buf);
529 76193d7c 2003-09-30 devnull *q0p = u.p0;
530 76193d7c 2003-09-30 devnull *q1p = u.p0+u.n;
531 76193d7c 2003-09-30 devnull break;
532 76193d7c 2003-09-30 devnull
533 76193d7c 2003-09-30 devnull case Filename:
534 76193d7c 2003-09-30 devnull f->seq = u.seq;
535 76193d7c 2003-09-30 devnull if(canredo)
536 76193d7c 2003-09-30 devnull fileunsetname(f, epsilon);
537 76193d7c 2003-09-30 devnull f->mod = u.mod;
538 76193d7c 2003-09-30 devnull up -= u.n;
539 76193d7c 2003-09-30 devnull
540 76193d7c 2003-09-30 devnull Strinsure(&f->name, u.n+1);
541 76193d7c 2003-09-30 devnull bufread(delta, up, f->name.s, u.n);
542 76193d7c 2003-09-30 devnull f->name.s[u.n] = 0;
543 76193d7c 2003-09-30 devnull f->name.n = u.n;
544 76193d7c 2003-09-30 devnull fixname(&f->name);
545 76193d7c 2003-09-30 devnull sortname(f);
546 76193d7c 2003-09-30 devnull break;
547 76193d7c 2003-09-30 devnull case Dot:
548 76193d7c 2003-09-30 devnull f->seq = u.seq;
549 76193d7c 2003-09-30 devnull if(canredo)
550 76193d7c 2003-09-30 devnull fileunsetdot(f, epsilon, f->dot.r);
551 76193d7c 2003-09-30 devnull f->mod = u.mod;
552 76193d7c 2003-09-30 devnull f->dot.r.p1 = u.p0;
553 76193d7c 2003-09-30 devnull f->dot.r.p2 = u.p0 + u.n;
554 76193d7c 2003-09-30 devnull break;
555 76193d7c 2003-09-30 devnull case Mark:
556 76193d7c 2003-09-30 devnull f->seq = u.seq;
557 76193d7c 2003-09-30 devnull if(canredo)
558 76193d7c 2003-09-30 devnull fileunsetmark(f, epsilon, f->mark);
559 76193d7c 2003-09-30 devnull f->mod = u.mod;
560 76193d7c 2003-09-30 devnull f->mark.p1 = u.p0;
561 76193d7c 2003-09-30 devnull f->mark.p2 = u.p0 + u.n;
562 76193d7c 2003-09-30 devnull break;
563 76193d7c 2003-09-30 devnull }
564 76193d7c 2003-09-30 devnull bufdelete(delta, up, delta->nc);
565 76193d7c 2003-09-30 devnull }
566 76193d7c 2003-09-30 devnull if(isundo)
567 76193d7c 2003-09-30 devnull f->seq = 0;
568 76193d7c 2003-09-30 devnull raspdone(f, flag);
569 76193d7c 2003-09-30 devnull }
570 76193d7c 2003-09-30 devnull
571 76193d7c 2003-09-30 devnull void
572 76193d7c 2003-09-30 devnull filereset(File *f)
573 76193d7c 2003-09-30 devnull {
574 76193d7c 2003-09-30 devnull bufreset(&f->delta);
575 76193d7c 2003-09-30 devnull bufreset(&f->epsilon);
576 76193d7c 2003-09-30 devnull f->seq = 0;
577 76193d7c 2003-09-30 devnull }
578 76193d7c 2003-09-30 devnull
579 76193d7c 2003-09-30 devnull void
580 76193d7c 2003-09-30 devnull fileclose(File *f)
581 76193d7c 2003-09-30 devnull {
582 76193d7c 2003-09-30 devnull Strclose(&f->name);
583 522b0689 2003-09-30 devnull bufclose(&f->b);
584 76193d7c 2003-09-30 devnull bufclose(&f->delta);
585 76193d7c 2003-09-30 devnull bufclose(&f->epsilon);
586 76193d7c 2003-09-30 devnull if(f->rasp)
587 76193d7c 2003-09-30 devnull listfree(f->rasp);
588 76193d7c 2003-09-30 devnull free(f);
589 76193d7c 2003-09-30 devnull }
590 76193d7c 2003-09-30 devnull
591 76193d7c 2003-09-30 devnull void
592 76193d7c 2003-09-30 devnull filemark(File *f)
593 76193d7c 2003-09-30 devnull {
594 76193d7c 2003-09-30 devnull
595 76193d7c 2003-09-30 devnull if(f->unread)
596 76193d7c 2003-09-30 devnull return;
597 76193d7c 2003-09-30 devnull if(f->epsilon.nc)
598 76193d7c 2003-09-30 devnull bufdelete(&f->epsilon, 0, f->epsilon.nc);
599 76193d7c 2003-09-30 devnull
600 76193d7c 2003-09-30 devnull if(f != cmd){
601 76193d7c 2003-09-30 devnull f->prevdot = f->dot.r;
602 76193d7c 2003-09-30 devnull f->prevmark = f->mark;
603 76193d7c 2003-09-30 devnull f->prevseq = f->seq;
604 76193d7c 2003-09-30 devnull f->prevmod = f->mod;
605 76193d7c 2003-09-30 devnull }
606 76193d7c 2003-09-30 devnull
607 76193d7c 2003-09-30 devnull f->ndot = f->dot;
608 76193d7c 2003-09-30 devnull f->seq = seq;
609 76193d7c 2003-09-30 devnull f->hiposn = 0;
610 76193d7c 2003-09-30 devnull }