Blame


1 b3994ec5 2003-12-11 devnull #include <u.h>
2 b3994ec5 2003-12-11 devnull #include <libc.h>
3 b3994ec5 2003-12-11 devnull #include <draw.h>
4 b3994ec5 2003-12-11 devnull #include <thread.h>
5 b3994ec5 2003-12-11 devnull #include <cursor.h>
6 b3994ec5 2003-12-11 devnull #include <mouse.h>
7 b3994ec5 2003-12-11 devnull #include <keyboard.h>
8 b3994ec5 2003-12-11 devnull #include <frame.h>
9 b3994ec5 2003-12-11 devnull #include <fcall.h>
10 b3994ec5 2003-12-11 devnull #include <plumb.h>
11 67dbeee5 2017-10-10 rsc #include <libsec.h>
12 b3994ec5 2003-12-11 devnull #include "dat.h"
13 b3994ec5 2003-12-11 devnull #include "fns.h"
14 b3994ec5 2003-12-11 devnull #include "edit.h"
15 b3994ec5 2003-12-11 devnull
16 b3994ec5 2003-12-11 devnull static char Wsequence[] = "warning: changes out of sequence\n";
17 b3994ec5 2003-12-11 devnull static int warned = FALSE;
18 b3994ec5 2003-12-11 devnull
19 b3994ec5 2003-12-11 devnull /*
20 b3994ec5 2003-12-11 devnull * Log of changes made by editing commands. Three reasons for this:
21 b3994ec5 2003-12-11 devnull * 1) We want addresses in commands to apply to old file, not file-in-change.
22 b3994ec5 2003-12-11 devnull * 2) It's difficult to track changes correctly as things move, e.g. ,x m$
23 b3994ec5 2003-12-11 devnull * 3) This gives an opportunity to optimize by merging adjacent changes.
24 b3994ec5 2003-12-11 devnull * It's a little bit like the Undo/Redo log in Files, but Point 3) argues for a
25 b3994ec5 2003-12-11 devnull * separate implementation. To do this well, we use Replace as well as
26 b3994ec5 2003-12-11 devnull * Insert and Delete
27 b3994ec5 2003-12-11 devnull */
28 b3994ec5 2003-12-11 devnull
29 b3994ec5 2003-12-11 devnull typedef struct Buflog Buflog;
30 b3994ec5 2003-12-11 devnull struct Buflog
31 b3994ec5 2003-12-11 devnull {
32 b3994ec5 2003-12-11 devnull short type; /* Replace, Filename */
33 b3994ec5 2003-12-11 devnull uint q0; /* location of change (unused in f) */
34 b3994ec5 2003-12-11 devnull uint nd; /* # runes to delete */
35 b3994ec5 2003-12-11 devnull uint nr; /* # runes in string or file name */
36 b3994ec5 2003-12-11 devnull };
37 b3994ec5 2003-12-11 devnull
38 b3994ec5 2003-12-11 devnull enum
39 b3994ec5 2003-12-11 devnull {
40 cbeb0b26 2006-04-01 devnull Buflogsize = sizeof(Buflog)/sizeof(Rune)
41 b3994ec5 2003-12-11 devnull };
42 b3994ec5 2003-12-11 devnull
43 b3994ec5 2003-12-11 devnull /*
44 b3994ec5 2003-12-11 devnull * Minstring shouldn't be very big or we will do lots of I/O for small changes.
45 b3994ec5 2003-12-11 devnull * Maxstring is RBUFSIZE so we can fbufalloc() once and not realloc elog.r.
46 b3994ec5 2003-12-11 devnull */
47 b3994ec5 2003-12-11 devnull enum
48 b3994ec5 2003-12-11 devnull {
49 b3994ec5 2003-12-11 devnull Minstring = 16, /* distance beneath which we merge changes */
50 cbeb0b26 2006-04-01 devnull Maxstring = RBUFSIZE /* maximum length of change we will merge into one */
51 b3994ec5 2003-12-11 devnull };
52 b3994ec5 2003-12-11 devnull
53 b3994ec5 2003-12-11 devnull void
54 b3994ec5 2003-12-11 devnull eloginit(File *f)
55 b3994ec5 2003-12-11 devnull {
56 b3994ec5 2003-12-11 devnull if(f->elog.type != Empty)
57 b3994ec5 2003-12-11 devnull return;
58 b3994ec5 2003-12-11 devnull f->elog.type = Null;
59 b3994ec5 2003-12-11 devnull if(f->elogbuf == nil)
60 b3994ec5 2003-12-11 devnull f->elogbuf = emalloc(sizeof(Buffer));
61 b3994ec5 2003-12-11 devnull if(f->elog.r == nil)
62 b3994ec5 2003-12-11 devnull f->elog.r = fbufalloc();
63 b3994ec5 2003-12-11 devnull bufreset(f->elogbuf);
64 b3994ec5 2003-12-11 devnull }
65 b3994ec5 2003-12-11 devnull
66 b3994ec5 2003-12-11 devnull void
67 b3994ec5 2003-12-11 devnull elogclose(File *f)
68 b3994ec5 2003-12-11 devnull {
69 b3994ec5 2003-12-11 devnull if(f->elogbuf){
70 b3994ec5 2003-12-11 devnull bufclose(f->elogbuf);
71 b3994ec5 2003-12-11 devnull free(f->elogbuf);
72 b3994ec5 2003-12-11 devnull f->elogbuf = nil;
73 b3994ec5 2003-12-11 devnull }
74 b3994ec5 2003-12-11 devnull }
75 b3994ec5 2003-12-11 devnull
76 b3994ec5 2003-12-11 devnull void
77 b3994ec5 2003-12-11 devnull elogreset(File *f)
78 b3994ec5 2003-12-11 devnull {
79 b3994ec5 2003-12-11 devnull f->elog.type = Null;
80 b3994ec5 2003-12-11 devnull f->elog.nd = 0;
81 b3994ec5 2003-12-11 devnull f->elog.nr = 0;
82 b3994ec5 2003-12-11 devnull }
83 b3994ec5 2003-12-11 devnull
84 b3994ec5 2003-12-11 devnull void
85 b3994ec5 2003-12-11 devnull elogterm(File *f)
86 b3994ec5 2003-12-11 devnull {
87 b3994ec5 2003-12-11 devnull elogreset(f);
88 b3994ec5 2003-12-11 devnull if(f->elogbuf)
89 b3994ec5 2003-12-11 devnull bufreset(f->elogbuf);
90 b3994ec5 2003-12-11 devnull f->elog.type = Empty;
91 b3994ec5 2003-12-11 devnull fbuffree(f->elog.r);
92 b3994ec5 2003-12-11 devnull f->elog.r = nil;
93 b3994ec5 2003-12-11 devnull warned = FALSE;
94 b3994ec5 2003-12-11 devnull }
95 b3994ec5 2003-12-11 devnull
96 b3994ec5 2003-12-11 devnull void
97 b3994ec5 2003-12-11 devnull elogflush(File *f)
98 b3994ec5 2003-12-11 devnull {
99 b3994ec5 2003-12-11 devnull Buflog b;
100 b3994ec5 2003-12-11 devnull
101 b3994ec5 2003-12-11 devnull b.type = f->elog.type;
102 b3994ec5 2003-12-11 devnull b.q0 = f->elog.q0;
103 b3994ec5 2003-12-11 devnull b.nd = f->elog.nd;
104 b3994ec5 2003-12-11 devnull b.nr = f->elog.nr;
105 b3994ec5 2003-12-11 devnull switch(f->elog.type){
106 b3994ec5 2003-12-11 devnull default:
107 b3994ec5 2003-12-11 devnull warning(nil, "unknown elog type 0x%ux\n", f->elog.type);
108 b3994ec5 2003-12-11 devnull break;
109 b3994ec5 2003-12-11 devnull case Null:
110 b3994ec5 2003-12-11 devnull break;
111 b3994ec5 2003-12-11 devnull case Insert:
112 b3994ec5 2003-12-11 devnull case Replace:
113 b3994ec5 2003-12-11 devnull if(f->elog.nr > 0)
114 b3994ec5 2003-12-11 devnull bufinsert(f->elogbuf, f->elogbuf->nc, f->elog.r, f->elog.nr);
115 b3994ec5 2003-12-11 devnull /* fall through */
116 b3994ec5 2003-12-11 devnull case Delete:
117 b3994ec5 2003-12-11 devnull bufinsert(f->elogbuf, f->elogbuf->nc, (Rune*)&b, Buflogsize);
118 b3994ec5 2003-12-11 devnull break;
119 b3994ec5 2003-12-11 devnull }
120 b3994ec5 2003-12-11 devnull elogreset(f);
121 b3994ec5 2003-12-11 devnull }
122 b3994ec5 2003-12-11 devnull
123 b3994ec5 2003-12-11 devnull void
124 b3994ec5 2003-12-11 devnull elogreplace(File *f, int q0, int q1, Rune *r, int nr)
125 b3994ec5 2003-12-11 devnull {
126 b3994ec5 2003-12-11 devnull uint gap;
127 b3994ec5 2003-12-11 devnull
128 b3994ec5 2003-12-11 devnull if(q0==q1 && nr==0)
129 b3994ec5 2003-12-11 devnull return;
130 b3994ec5 2003-12-11 devnull eloginit(f);
131 b3994ec5 2003-12-11 devnull if(f->elog.type!=Null && q0<f->elog.q0){
132 b3994ec5 2003-12-11 devnull if(warned++ == 0)
133 b3994ec5 2003-12-11 devnull warning(nil, Wsequence);
134 b3994ec5 2003-12-11 devnull elogflush(f);
135 b3994ec5 2003-12-11 devnull }
136 b3994ec5 2003-12-11 devnull /* try to merge with previous */
137 b3994ec5 2003-12-11 devnull gap = q0 - (f->elog.q0+f->elog.nd); /* gap between previous and this */
138 b3994ec5 2003-12-11 devnull if(f->elog.type==Replace && f->elog.nr+gap+nr<Maxstring){
139 b3994ec5 2003-12-11 devnull if(gap < Minstring){
140 b3994ec5 2003-12-11 devnull if(gap > 0){
141 b3994ec5 2003-12-11 devnull bufread(&f->b, f->elog.q0+f->elog.nd, f->elog.r+f->elog.nr, gap);
142 b3994ec5 2003-12-11 devnull f->elog.nr += gap;
143 b3994ec5 2003-12-11 devnull }
144 b3994ec5 2003-12-11 devnull f->elog.nd += gap + q1-q0;
145 b3994ec5 2003-12-11 devnull runemove(f->elog.r+f->elog.nr, r, nr);
146 b3994ec5 2003-12-11 devnull f->elog.nr += nr;
147 b3994ec5 2003-12-11 devnull return;
148 b3994ec5 2003-12-11 devnull }
149 b3994ec5 2003-12-11 devnull }
150 b3994ec5 2003-12-11 devnull elogflush(f);
151 b3994ec5 2003-12-11 devnull f->elog.type = Replace;
152 b3994ec5 2003-12-11 devnull f->elog.q0 = q0;
153 b3994ec5 2003-12-11 devnull f->elog.nd = q1-q0;
154 b3994ec5 2003-12-11 devnull f->elog.nr = nr;
155 b3994ec5 2003-12-11 devnull if(nr > RBUFSIZE)
156 b3994ec5 2003-12-11 devnull editerror("internal error: replacement string too large(%d)", nr);
157 b3994ec5 2003-12-11 devnull runemove(f->elog.r, r, nr);
158 b3994ec5 2003-12-11 devnull }
159 b3994ec5 2003-12-11 devnull
160 b3994ec5 2003-12-11 devnull void
161 b3994ec5 2003-12-11 devnull eloginsert(File *f, int q0, Rune *r, int nr)
162 b3994ec5 2003-12-11 devnull {
163 b3994ec5 2003-12-11 devnull int n;
164 b3994ec5 2003-12-11 devnull
165 b3994ec5 2003-12-11 devnull if(nr == 0)
166 b3994ec5 2003-12-11 devnull return;
167 b3994ec5 2003-12-11 devnull eloginit(f);
168 b3994ec5 2003-12-11 devnull if(f->elog.type!=Null && q0<f->elog.q0){
169 b3994ec5 2003-12-11 devnull if(warned++ == 0)
170 b3994ec5 2003-12-11 devnull warning(nil, Wsequence);
171 b3994ec5 2003-12-11 devnull elogflush(f);
172 b3994ec5 2003-12-11 devnull }
173 b3994ec5 2003-12-11 devnull /* try to merge with previous */
174 2277c5d7 2004-03-21 devnull if(f->elog.type==Insert && q0==f->elog.q0 && f->elog.nr+nr<Maxstring){
175 b3994ec5 2003-12-11 devnull runemove(f->elog.r+f->elog.nr, r, nr);
176 b3994ec5 2003-12-11 devnull f->elog.nr += nr;
177 b3994ec5 2003-12-11 devnull return;
178 b3994ec5 2003-12-11 devnull }
179 b3994ec5 2003-12-11 devnull while(nr > 0){
180 b3994ec5 2003-12-11 devnull elogflush(f);
181 b3994ec5 2003-12-11 devnull f->elog.type = Insert;
182 b3994ec5 2003-12-11 devnull f->elog.q0 = q0;
183 b3994ec5 2003-12-11 devnull n = nr;
184 b3994ec5 2003-12-11 devnull if(n > RBUFSIZE)
185 b3994ec5 2003-12-11 devnull n = RBUFSIZE;
186 b3994ec5 2003-12-11 devnull f->elog.nr = n;
187 b3994ec5 2003-12-11 devnull runemove(f->elog.r, r, n);
188 b3994ec5 2003-12-11 devnull r += n;
189 b3994ec5 2003-12-11 devnull nr -= n;
190 b3994ec5 2003-12-11 devnull }
191 b3994ec5 2003-12-11 devnull }
192 b3994ec5 2003-12-11 devnull
193 b3994ec5 2003-12-11 devnull void
194 b3994ec5 2003-12-11 devnull elogdelete(File *f, int q0, int q1)
195 b3994ec5 2003-12-11 devnull {
196 b3994ec5 2003-12-11 devnull if(q0 == q1)
197 b3994ec5 2003-12-11 devnull return;
198 b3994ec5 2003-12-11 devnull eloginit(f);
199 b3994ec5 2003-12-11 devnull if(f->elog.type!=Null && q0<f->elog.q0+f->elog.nd){
200 b3994ec5 2003-12-11 devnull if(warned++ == 0)
201 b3994ec5 2003-12-11 devnull warning(nil, Wsequence);
202 b3994ec5 2003-12-11 devnull elogflush(f);
203 b3994ec5 2003-12-11 devnull }
204 b3994ec5 2003-12-11 devnull /* try to merge with previous */
205 b3994ec5 2003-12-11 devnull if(f->elog.type==Delete && f->elog.q0+f->elog.nd==q0){
206 b3994ec5 2003-12-11 devnull f->elog.nd += q1-q0;
207 b3994ec5 2003-12-11 devnull return;
208 b3994ec5 2003-12-11 devnull }
209 b3994ec5 2003-12-11 devnull elogflush(f);
210 b3994ec5 2003-12-11 devnull f->elog.type = Delete;
211 b3994ec5 2003-12-11 devnull f->elog.q0 = q0;
212 b3994ec5 2003-12-11 devnull f->elog.nd = q1-q0;
213 b3994ec5 2003-12-11 devnull }
214 b3994ec5 2003-12-11 devnull
215 b3994ec5 2003-12-11 devnull #define tracelog 0
216 b3994ec5 2003-12-11 devnull void
217 b3994ec5 2003-12-11 devnull elogapply(File *f)
218 b3994ec5 2003-12-11 devnull {
219 b3994ec5 2003-12-11 devnull Buflog b;
220 b3994ec5 2003-12-11 devnull Rune *buf;
221 b3994ec5 2003-12-11 devnull uint i, n, up, mod;
222 5e77b8bb 2005-03-23 devnull uint tq0, tq1;
223 b3994ec5 2003-12-11 devnull Buffer *log;
224 b3994ec5 2003-12-11 devnull Text *t;
225 f0315273 2008-06-01 rsc int owner;
226 b3994ec5 2003-12-11 devnull
227 b3994ec5 2003-12-11 devnull elogflush(f);
228 b3994ec5 2003-12-11 devnull log = f->elogbuf;
229 b3994ec5 2003-12-11 devnull t = f->curtext;
230 b3994ec5 2003-12-11 devnull
231 b3994ec5 2003-12-11 devnull buf = fbufalloc();
232 b3994ec5 2003-12-11 devnull mod = FALSE;
233 b3994ec5 2003-12-11 devnull
234 f0315273 2008-06-01 rsc owner = 0;
235 f0315273 2008-06-01 rsc if(t->w){
236 f0315273 2008-06-01 rsc owner = t->w->owner;
237 f0315273 2008-06-01 rsc if(owner == 0)
238 f0315273 2008-06-01 rsc t->w->owner = 'E';
239 f0315273 2008-06-01 rsc }
240 f0315273 2008-06-01 rsc
241 b3994ec5 2003-12-11 devnull /*
242 5e77b8bb 2005-03-23 devnull * The edit commands have already updated the selection in t->q0, t->q1,
243 5e77b8bb 2005-03-23 devnull * but using coordinates relative to the unmodified buffer. As we apply the log,
244 5e77b8bb 2005-03-23 devnull * we have to update the coordinates to be relative to the modified buffer.
245 5e77b8bb 2005-03-23 devnull * Textinsert and textdelete will do this for us; our only work is to apply the
246 fa325e9b 2020-01-10 cross * convention that an insertion at t->q0==t->q1 is intended to select the
247 5e77b8bb 2005-03-23 devnull * inserted text.
248 b3994ec5 2003-12-11 devnull */
249 5e77b8bb 2005-03-23 devnull
250 b3994ec5 2003-12-11 devnull /*
251 b3994ec5 2003-12-11 devnull * We constrain the addresses in here (with textconstrain()) because
252 b3994ec5 2003-12-11 devnull * overlapping changes will generate bogus addresses. We will warn
253 b3994ec5 2003-12-11 devnull * about changes out of sequence but proceed anyway; here we must
254 b3994ec5 2003-12-11 devnull * keep things in range.
255 b3994ec5 2003-12-11 devnull */
256 b3994ec5 2003-12-11 devnull
257 b3994ec5 2003-12-11 devnull while(log->nc > 0){
258 b3994ec5 2003-12-11 devnull up = log->nc-Buflogsize;
259 b3994ec5 2003-12-11 devnull bufread(log, up, (Rune*)&b, Buflogsize);
260 b3994ec5 2003-12-11 devnull switch(b.type){
261 b3994ec5 2003-12-11 devnull default:
262 b3994ec5 2003-12-11 devnull fprint(2, "elogapply: 0x%ux\n", b.type);
263 b3994ec5 2003-12-11 devnull abort();
264 b3994ec5 2003-12-11 devnull break;
265 b3994ec5 2003-12-11 devnull
266 b3994ec5 2003-12-11 devnull case Replace:
267 b3994ec5 2003-12-11 devnull if(tracelog)
268 5e77b8bb 2005-03-23 devnull warning(nil, "elog replace %d %d (%d %d)\n",
269 5e77b8bb 2005-03-23 devnull b.q0, b.q0+b.nd, t->q0, t->q1);
270 b3994ec5 2003-12-11 devnull if(!mod){
271 b3994ec5 2003-12-11 devnull mod = TRUE;
272 b3994ec5 2003-12-11 devnull filemark(f);
273 b3994ec5 2003-12-11 devnull }
274 b3994ec5 2003-12-11 devnull textconstrain(t, b.q0, b.q0+b.nd, &tq0, &tq1);
275 b3994ec5 2003-12-11 devnull textdelete(t, tq0, tq1, TRUE);
276 b3994ec5 2003-12-11 devnull up -= b.nr;
277 b3994ec5 2003-12-11 devnull for(i=0; i<b.nr; i+=n){
278 b3994ec5 2003-12-11 devnull n = b.nr - i;
279 b3994ec5 2003-12-11 devnull if(n > RBUFSIZE)
280 b3994ec5 2003-12-11 devnull n = RBUFSIZE;
281 b3994ec5 2003-12-11 devnull bufread(log, up+i, buf, n);
282 b3994ec5 2003-12-11 devnull textinsert(t, tq0+i, buf, n, TRUE);
283 b3994ec5 2003-12-11 devnull }
284 5e77b8bb 2005-03-23 devnull if(t->q0 == b.q0 && t->q1 == b.q0)
285 5e77b8bb 2005-03-23 devnull t->q1 += b.nr;
286 b3994ec5 2003-12-11 devnull break;
287 b3994ec5 2003-12-11 devnull
288 b3994ec5 2003-12-11 devnull case Delete:
289 b3994ec5 2003-12-11 devnull if(tracelog)
290 5e77b8bb 2005-03-23 devnull warning(nil, "elog delete %d %d (%d %d)\n",
291 5e77b8bb 2005-03-23 devnull b.q0, b.q0+b.nd, t->q0, t->q1);
292 b3994ec5 2003-12-11 devnull if(!mod){
293 b3994ec5 2003-12-11 devnull mod = TRUE;
294 b3994ec5 2003-12-11 devnull filemark(f);
295 b3994ec5 2003-12-11 devnull }
296 b3994ec5 2003-12-11 devnull textconstrain(t, b.q0, b.q0+b.nd, &tq0, &tq1);
297 b3994ec5 2003-12-11 devnull textdelete(t, tq0, tq1, TRUE);
298 b3994ec5 2003-12-11 devnull break;
299 b3994ec5 2003-12-11 devnull
300 b3994ec5 2003-12-11 devnull case Insert:
301 b3994ec5 2003-12-11 devnull if(tracelog)
302 5e77b8bb 2005-03-23 devnull warning(nil, "elog insert %d %d (%d %d)\n",
303 5e77b8bb 2005-03-23 devnull b.q0, b.q0+b.nr, t->q0, t->q1);
304 b3994ec5 2003-12-11 devnull if(!mod){
305 b3994ec5 2003-12-11 devnull mod = TRUE;
306 b3994ec5 2003-12-11 devnull filemark(f);
307 b3994ec5 2003-12-11 devnull }
308 b3994ec5 2003-12-11 devnull textconstrain(t, b.q0, b.q0, &tq0, &tq1);
309 b3994ec5 2003-12-11 devnull up -= b.nr;
310 b3994ec5 2003-12-11 devnull for(i=0; i<b.nr; i+=n){
311 b3994ec5 2003-12-11 devnull n = b.nr - i;
312 b3994ec5 2003-12-11 devnull if(n > RBUFSIZE)
313 b3994ec5 2003-12-11 devnull n = RBUFSIZE;
314 b3994ec5 2003-12-11 devnull bufread(log, up+i, buf, n);
315 b3994ec5 2003-12-11 devnull textinsert(t, tq0+i, buf, n, TRUE);
316 b3994ec5 2003-12-11 devnull }
317 5e77b8bb 2005-03-23 devnull if(t->q0 == b.q0 && t->q1 == b.q0)
318 5e77b8bb 2005-03-23 devnull t->q1 += b.nr;
319 b3994ec5 2003-12-11 devnull break;
320 b3994ec5 2003-12-11 devnull
321 b3994ec5 2003-12-11 devnull /* case Filename:
322 b3994ec5 2003-12-11 devnull f->seq = u.seq;
323 b3994ec5 2003-12-11 devnull fileunsetname(f, epsilon);
324 b3994ec5 2003-12-11 devnull f->mod = u.mod;
325 b3994ec5 2003-12-11 devnull up -= u.n;
326 b3994ec5 2003-12-11 devnull free(f->name);
327 b3994ec5 2003-12-11 devnull if(u.n == 0)
328 b3994ec5 2003-12-11 devnull f->name = nil;
329 b3994ec5 2003-12-11 devnull else
330 b3994ec5 2003-12-11 devnull f->name = runemalloc(u.n);
331 b3994ec5 2003-12-11 devnull bufread(delta, up, f->name, u.n);
332 b3994ec5 2003-12-11 devnull f->nname = u.n;
333 b3994ec5 2003-12-11 devnull break;
334 b3994ec5 2003-12-11 devnull */
335 b3994ec5 2003-12-11 devnull }
336 b3994ec5 2003-12-11 devnull bufdelete(log, up, log->nc);
337 b3994ec5 2003-12-11 devnull }
338 b3994ec5 2003-12-11 devnull fbuffree(buf);
339 b3994ec5 2003-12-11 devnull elogterm(f);
340 fa325e9b 2020-01-10 cross
341 b3994ec5 2003-12-11 devnull /*
342 5e77b8bb 2005-03-23 devnull * Bad addresses will cause bufload to crash, so double check.
343 5e77b8bb 2005-03-23 devnull * If changes were out of order, we expect problems so don't complain further.
344 b3994ec5 2003-12-11 devnull */
345 5e77b8bb 2005-03-23 devnull if(t->q0 > f->b.nc || t->q1 > f->b.nc || t->q0 > t->q1){
346 5e77b8bb 2005-03-23 devnull if(!warned)
347 5e77b8bb 2005-03-23 devnull warning(nil, "elogapply: can't happen %d %d %d\n", t->q0, t->q1, f->b.nc);
348 5e77b8bb 2005-03-23 devnull t->q1 = min(t->q1, f->b.nc);
349 5e77b8bb 2005-03-23 devnull t->q0 = min(t->q0, t->q1);
350 b3994ec5 2003-12-11 devnull }
351 f0315273 2008-06-01 rsc
352 f0315273 2008-06-01 rsc if(t->w)
353 f0315273 2008-06-01 rsc t->w->owner = owner;
354 b3994ec5 2003-12-11 devnull }