1 76193d7c 2003-09-30 devnull #include "sam.h"
2 76193d7c 2003-09-30 devnull #include "parse.h"
4 76193d7c 2003-09-30 devnull int Glooping;
7 76193d7c 2003-09-30 devnull int append(File*, Cmd*, Posn);
8 76193d7c 2003-09-30 devnull int display(File*);
9 76193d7c 2003-09-30 devnull void looper(File*, Cmd*, int);
10 76193d7c 2003-09-30 devnull void filelooper(Cmd*, int);
11 76193d7c 2003-09-30 devnull void linelooper(File*, Cmd*);
14 76193d7c 2003-09-30 devnull resetxec(void)
16 76193d7c 2003-09-30 devnull Glooping = nest = 0;
20 76193d7c 2003-09-30 devnull cmdexec(File *f, Cmd *cp)
23 76193d7c 2003-09-30 devnull Addr *ap;
24 76193d7c 2003-09-30 devnull Address a;
26 76193d7c 2003-09-30 devnull if(f && f->unread)
28 76193d7c 2003-09-30 devnull if(f==0 && (cp->addr==0 || cp->addr->type!='"') &&
29 76193d7c 2003-09-30 devnull !utfrune("bBnqUXY!", cp->cmdc) &&
30 76193d7c 2003-09-30 devnull cp->cmdc!=('c'|0x100) && !(cp->cmdc=='D' && cp->ctext))
31 76193d7c 2003-09-30 devnull error(Enofile);
32 76193d7c 2003-09-30 devnull i = lookup(cp->cmdc);
33 76193d7c 2003-09-30 devnull if(i >= 0 && cmdtab[i].defaddr != aNo){
34 76193d7c 2003-09-30 devnull if((ap=cp->addr)==0 && cp->cmdc!='\n'){
35 76193d7c 2003-09-30 devnull cp->addr = ap = newaddr();
36 76193d7c 2003-09-30 devnull ap->type = '.';
37 76193d7c 2003-09-30 devnull if(cmdtab[i].defaddr == aAll)
38 76193d7c 2003-09-30 devnull ap->type = '*';
39 76193d7c 2003-09-30 devnull }else if(ap && ap->type=='"' && ap->next==0 && cp->cmdc!='\n'){
40 76193d7c 2003-09-30 devnull ap->next = newaddr();
41 76193d7c 2003-09-30 devnull ap->next->type = '.';
42 76193d7c 2003-09-30 devnull if(cmdtab[i].defaddr == aAll)
43 76193d7c 2003-09-30 devnull ap->next->type = '*';
45 76193d7c 2003-09-30 devnull if(cp->addr){ /* may be false for '\n' (only) */
46 76193d7c 2003-09-30 devnull static Address none = {0,0,0};
48 76193d7c 2003-09-30 devnull addr = address(ap, f->dot, 0);
49 76193d7c 2003-09-30 devnull else /* a " */
50 76193d7c 2003-09-30 devnull addr = address(ap, none, 0);
51 76193d7c 2003-09-30 devnull f = addr.f;
54 76193d7c 2003-09-30 devnull current(f);
55 76193d7c 2003-09-30 devnull switch(cp->cmdc){
56 76193d7c 2003-09-30 devnull case '{':
57 76193d7c 2003-09-30 devnull a = cp->addr? address(cp->addr, f->dot, 0): f->dot;
58 76193d7c 2003-09-30 devnull for(cp = cp->ccmd; cp; cp = cp->next){
59 76193d7c 2003-09-30 devnull a.f->dot = a;
60 76193d7c 2003-09-30 devnull cmdexec(a.f, cp);
64 76193d7c 2003-09-30 devnull i=(*cmdtab[i].fn)(f, cp);
65 76193d7c 2003-09-30 devnull return i;
67 76193d7c 2003-09-30 devnull return 1;
72 76193d7c 2003-09-30 devnull a_cmd(File *f, Cmd *cp)
74 76193d7c 2003-09-30 devnull return append(f, cp, addr.r.p2);
78 76193d7c 2003-09-30 devnull b_cmd(File *f, Cmd *cp)
81 76193d7c 2003-09-30 devnull f = cp->cmdc=='b'? tofile(cp->ctext) : getfile(cp->ctext);
82 76193d7c 2003-09-30 devnull if(f->unread)
84 76193d7c 2003-09-30 devnull else if(nest == 0)
85 76193d7c 2003-09-30 devnull filename(f);
86 76193d7c 2003-09-30 devnull return TRUE;
90 76193d7c 2003-09-30 devnull c_cmd(File *f, Cmd *cp)
92 76193d7c 2003-09-30 devnull logdelete(f, addr.r.p1, addr.r.p2);
93 76193d7c 2003-09-30 devnull f->ndot.r.p1 = f->ndot.r.p2 = addr.r.p2;
94 76193d7c 2003-09-30 devnull return append(f, cp, addr.r.p2);
98 76193d7c 2003-09-30 devnull d_cmd(File *f, Cmd *cp)
100 76193d7c 2003-09-30 devnull USED(cp);
101 76193d7c 2003-09-30 devnull logdelete(f, addr.r.p1, addr.r.p2);
102 76193d7c 2003-09-30 devnull f->ndot.r.p1 = f->ndot.r.p2 = addr.r.p1;
103 76193d7c 2003-09-30 devnull return TRUE;
107 76193d7c 2003-09-30 devnull D_cmd(File *f, Cmd *cp)
109 76193d7c 2003-09-30 devnull closefiles(f, cp->ctext);
110 76193d7c 2003-09-30 devnull return TRUE;
114 76193d7c 2003-09-30 devnull e_cmd(File *f, Cmd *cp)
116 76193d7c 2003-09-30 devnull if(getname(f, cp->ctext, cp->cmdc=='e')==0)
117 76193d7c 2003-09-30 devnull error(Enoname);
118 76193d7c 2003-09-30 devnull edit(f, cp->cmdc);
119 76193d7c 2003-09-30 devnull return TRUE;
123 76193d7c 2003-09-30 devnull f_cmd(File *f, Cmd *cp)
125 76193d7c 2003-09-30 devnull getname(f, cp->ctext, TRUE);
126 76193d7c 2003-09-30 devnull filename(f);
127 76193d7c 2003-09-30 devnull return TRUE;
131 76193d7c 2003-09-30 devnull g_cmd(File *f, Cmd *cp)
133 76193d7c 2003-09-30 devnull if(f!=addr.f)panic("g_cmd f!=addr.f");
134 76193d7c 2003-09-30 devnull compile(cp->re);
135 76193d7c 2003-09-30 devnull if(execute(f, addr.r.p1, addr.r.p2) ^ cp->cmdc=='v'){
136 76193d7c 2003-09-30 devnull f->dot = addr;
137 76193d7c 2003-09-30 devnull return cmdexec(f, cp->ccmd);
139 76193d7c 2003-09-30 devnull return TRUE;
143 76193d7c 2003-09-30 devnull i_cmd(File *f, Cmd *cp)
145 76193d7c 2003-09-30 devnull return append(f, cp, addr.r.p1);
149 76193d7c 2003-09-30 devnull k_cmd(File *f, Cmd *cp)
151 76193d7c 2003-09-30 devnull USED(cp);
152 76193d7c 2003-09-30 devnull f->mark = addr.r;
153 76193d7c 2003-09-30 devnull return TRUE;
157 76193d7c 2003-09-30 devnull m_cmd(File *f, Cmd *cp)
159 76193d7c 2003-09-30 devnull Address addr2;
161 76193d7c 2003-09-30 devnull addr2 = address(cp->caddr, f->dot, 0);
162 76193d7c 2003-09-30 devnull if(cp->cmdc=='m')
163 76193d7c 2003-09-30 devnull move(f, addr2);
165 76193d7c 2003-09-30 devnull copy(f, addr2);
166 76193d7c 2003-09-30 devnull return TRUE;
170 76193d7c 2003-09-30 devnull n_cmd(File *f, Cmd *cp)
173 76193d7c 2003-09-30 devnull USED(f);
174 76193d7c 2003-09-30 devnull USED(cp);
175 76193d7c 2003-09-30 devnull for(i = 0; i<file.nused; i++){
176 76193d7c 2003-09-30 devnull if(file.filepptr[i] == cmd)
177 76193d7c 2003-09-30 devnull continue;
178 76193d7c 2003-09-30 devnull f = file.filepptr[i];
179 76193d7c 2003-09-30 devnull Strduplstr(&genstr, &f->name);
180 76193d7c 2003-09-30 devnull filename(f);
182 76193d7c 2003-09-30 devnull return TRUE;
186 76193d7c 2003-09-30 devnull p_cmd(File *f, Cmd *cp)
188 76193d7c 2003-09-30 devnull USED(cp);
189 76193d7c 2003-09-30 devnull return display(f);
193 76193d7c 2003-09-30 devnull q_cmd(File *f, Cmd *cp)
195 76193d7c 2003-09-30 devnull USED(cp);
196 76193d7c 2003-09-30 devnull USED(f);
197 76193d7c 2003-09-30 devnull trytoquit();
198 76193d7c 2003-09-30 devnull if(downloaded){
199 76193d7c 2003-09-30 devnull outT0(Hexit);
200 76193d7c 2003-09-30 devnull return TRUE;
202 76193d7c 2003-09-30 devnull return FALSE;
206 76193d7c 2003-09-30 devnull s_cmd(File *f, Cmd *cp)
208 76193d7c 2003-09-30 devnull int i, j, c, n;
209 76193d7c 2003-09-30 devnull Posn p1, op, didsub = 0, delta = 0;
211 76193d7c 2003-09-30 devnull n = cp->num;
213 76193d7c 2003-09-30 devnull compile(cp->re);
214 76193d7c 2003-09-30 devnull for(p1 = addr.r.p1; p1<=addr.r.p2 && execute(f, p1, addr.r.p2); ){
215 76193d7c 2003-09-30 devnull if(sel.p[0].p1==sel.p[0].p2){ /* empty match? */
216 76193d7c 2003-09-30 devnull if(sel.p[0].p1==op){
218 76193d7c 2003-09-30 devnull continue;
220 76193d7c 2003-09-30 devnull p1 = sel.p[0].p2+1;
222 76193d7c 2003-09-30 devnull p1 = sel.p[0].p2;
223 76193d7c 2003-09-30 devnull op = sel.p[0].p2;
224 76193d7c 2003-09-30 devnull if(--n>0)
225 76193d7c 2003-09-30 devnull continue;
226 76193d7c 2003-09-30 devnull Strzero(&genstr);
227 76193d7c 2003-09-30 devnull for(i = 0; i<cp->ctext->n; i++)
228 76193d7c 2003-09-30 devnull if((c = cp->ctext->s[i])=='\\' && i<cp->ctext->n-1){
229 76193d7c 2003-09-30 devnull c = cp->ctext->s[++i];
230 76193d7c 2003-09-30 devnull if('1'<=c && c<='9') {
231 76193d7c 2003-09-30 devnull j = c-'0';
232 76193d7c 2003-09-30 devnull if(sel.p[j].p2-sel.p[j].p1>BLOCKSIZE)
233 76193d7c 2003-09-30 devnull error(Elongtag);
234 522b0689 2003-09-30 devnull bufread(&f->b, sel.p[j].p1, genbuf, sel.p[j].p2-sel.p[j].p1);
235 76193d7c 2003-09-30 devnull Strinsert(&genstr, tmprstr(genbuf, (sel.p[j].p2-sel.p[j].p1)), genstr.n);
237 76193d7c 2003-09-30 devnull Straddc(&genstr, c);
238 76193d7c 2003-09-30 devnull }else if(c!='&')
239 76193d7c 2003-09-30 devnull Straddc(&genstr, c);
241 76193d7c 2003-09-30 devnull if(sel.p[0].p2-sel.p[0].p1>BLOCKSIZE)
242 76193d7c 2003-09-30 devnull error(Elongrhs);
243 522b0689 2003-09-30 devnull bufread(&f->b, sel.p[0].p1, genbuf, sel.p[0].p2-sel.p[0].p1);
244 76193d7c 2003-09-30 devnull Strinsert(&genstr,
245 76193d7c 2003-09-30 devnull tmprstr(genbuf, (int)(sel.p[0].p2-sel.p[0].p1)),
246 76193d7c 2003-09-30 devnull genstr.n);
248 76193d7c 2003-09-30 devnull if(sel.p[0].p1!=sel.p[0].p2){
249 76193d7c 2003-09-30 devnull logdelete(f, sel.p[0].p1, sel.p[0].p2);
250 76193d7c 2003-09-30 devnull delta-=sel.p[0].p2-sel.p[0].p1;
252 76193d7c 2003-09-30 devnull if(genstr.n){
253 76193d7c 2003-09-30 devnull loginsert(f, sel.p[0].p2, genstr.s, genstr.n);
254 76193d7c 2003-09-30 devnull delta+=genstr.n;
256 76193d7c 2003-09-30 devnull didsub = 1;
257 76193d7c 2003-09-30 devnull if(!cp->flag)
260 76193d7c 2003-09-30 devnull if(!didsub && nest==0)
261 76193d7c 2003-09-30 devnull error(Enosub);
262 76193d7c 2003-09-30 devnull f->ndot.r.p1 = addr.r.p1, f->ndot.r.p2 = addr.r.p2+delta;
263 76193d7c 2003-09-30 devnull return TRUE;
267 76193d7c 2003-09-30 devnull u_cmd(File *f, Cmd *cp)
271 76193d7c 2003-09-30 devnull USED(f);
272 76193d7c 2003-09-30 devnull USED(cp);
273 76193d7c 2003-09-30 devnull n = cp->num;
274 76193d7c 2003-09-30 devnull if(n >= 0)
275 76193d7c 2003-09-30 devnull while(n-- && undo(TRUE))
278 76193d7c 2003-09-30 devnull while(n++ && undo(FALSE))
280 76193d7c 2003-09-30 devnull return TRUE;
284 76193d7c 2003-09-30 devnull w_cmd(File *f, Cmd *cp)
286 76193d7c 2003-09-30 devnull int fseq;
288 76193d7c 2003-09-30 devnull fseq = f->seq;
289 76193d7c 2003-09-30 devnull if(getname(f, cp->ctext, FALSE)==0)
290 76193d7c 2003-09-30 devnull error(Enoname);
291 76193d7c 2003-09-30 devnull if(fseq == seq)
292 76193d7c 2003-09-30 devnull error_s(Ewseq, genc);
293 76193d7c 2003-09-30 devnull writef(f);
294 76193d7c 2003-09-30 devnull return TRUE;
298 76193d7c 2003-09-30 devnull x_cmd(File *f, Cmd *cp)
300 76193d7c 2003-09-30 devnull if(cp->re)
301 76193d7c 2003-09-30 devnull looper(f, cp, cp->cmdc=='x');
303 76193d7c 2003-09-30 devnull linelooper(f, cp);
304 76193d7c 2003-09-30 devnull return TRUE;
308 76193d7c 2003-09-30 devnull X_cmd(File *f, Cmd *cp)
310 76193d7c 2003-09-30 devnull USED(f);
311 76193d7c 2003-09-30 devnull filelooper(cp, cp->cmdc=='X');
312 76193d7c 2003-09-30 devnull return TRUE;
316 76193d7c 2003-09-30 devnull plan9_cmd(File *f, Cmd *cp)
318 76193d7c 2003-09-30 devnull plan9(f, cp->cmdc, cp->ctext, nest);
319 76193d7c 2003-09-30 devnull return TRUE;
323 76193d7c 2003-09-30 devnull eq_cmd(File *f, Cmd *cp)
325 76193d7c 2003-09-30 devnull int charsonly;
327 76193d7c 2003-09-30 devnull switch(cp->ctext->n){
329 76193d7c 2003-09-30 devnull charsonly = FALSE;
332 76193d7c 2003-09-30 devnull if(cp->ctext->s[0]=='#'){
333 76193d7c 2003-09-30 devnull charsonly = TRUE;
336 76193d7c 2003-09-30 devnull default:
337 76193d7c 2003-09-30 devnull SET(charsonly);
338 76193d7c 2003-09-30 devnull error(Enewline);
340 76193d7c 2003-09-30 devnull printposn(f, charsonly);
341 76193d7c 2003-09-30 devnull return TRUE;
345 76193d7c 2003-09-30 devnull nl_cmd(File *f, Cmd *cp)
347 76193d7c 2003-09-30 devnull Address a;
349 76193d7c 2003-09-30 devnull if(cp->addr == 0){
350 76193d7c 2003-09-30 devnull /* First put it on newline boundaries */
351 76193d7c 2003-09-30 devnull addr = lineaddr((Posn)0, f->dot, -1);
352 76193d7c 2003-09-30 devnull a = lineaddr((Posn)0, f->dot, 1);
353 76193d7c 2003-09-30 devnull addr.r.p2 = a.r.p2;
354 76193d7c 2003-09-30 devnull if(addr.r.p1==f->dot.r.p1 && addr.r.p2==f->dot.r.p2)
355 76193d7c 2003-09-30 devnull addr = lineaddr((Posn)1, f->dot, 1);
356 76193d7c 2003-09-30 devnull display(f);
357 76193d7c 2003-09-30 devnull }else if(downloaded)
358 76193d7c 2003-09-30 devnull moveto(f, addr.r);
360 76193d7c 2003-09-30 devnull display(f);
361 76193d7c 2003-09-30 devnull return TRUE;
365 76193d7c 2003-09-30 devnull cd_cmd(File *f, Cmd *cp)
367 76193d7c 2003-09-30 devnull USED(f);
368 76193d7c 2003-09-30 devnull cd(cp->ctext);
369 76193d7c 2003-09-30 devnull return TRUE;
373 76193d7c 2003-09-30 devnull append(File *f, Cmd *cp, Posn p)
375 76193d7c 2003-09-30 devnull if(cp->ctext->n>0 && cp->ctext->s[cp->ctext->n-1]==0)
376 76193d7c 2003-09-30 devnull --cp->ctext->n;
377 76193d7c 2003-09-30 devnull if(cp->ctext->n>0)
378 76193d7c 2003-09-30 devnull loginsert(f, p, cp->ctext->s, cp->ctext->n);
379 76193d7c 2003-09-30 devnull f->ndot.r.p1 = p;
380 76193d7c 2003-09-30 devnull f->ndot.r.p2 = p+cp->ctext->n;
381 76193d7c 2003-09-30 devnull return TRUE;
385 76193d7c 2003-09-30 devnull display(File *f)
387 76193d7c 2003-09-30 devnull Posn p1, p2;
389 76193d7c 2003-09-30 devnull char *c;
391 76193d7c 2003-09-30 devnull p1 = addr.r.p1;
392 76193d7c 2003-09-30 devnull p2 = addr.r.p2;
393 522b0689 2003-09-30 devnull if(p2 > f->b.nc){
394 522b0689 2003-09-30 devnull fprint(2, "bad display addr p1=%ld p2=%ld f->b.nc=%d\n", p1, p2, f->b.nc); /*ZZZ should never happen, can remove */
395 522b0689 2003-09-30 devnull p2 = f->b.nc;
397 76193d7c 2003-09-30 devnull while(p1 < p2){
398 76193d7c 2003-09-30 devnull np = p2-p1;
399 76193d7c 2003-09-30 devnull if(np>BLOCKSIZE-1)
400 76193d7c 2003-09-30 devnull np = BLOCKSIZE-1;
401 522b0689 2003-09-30 devnull bufread(&f->b, p1, genbuf, np);
402 76193d7c 2003-09-30 devnull genbuf[np] = 0;
403 76193d7c 2003-09-30 devnull c = Strtoc(tmprstr(genbuf, np+1));
404 76193d7c 2003-09-30 devnull if(downloaded)
405 76193d7c 2003-09-30 devnull termwrite(c);
407 76193d7c 2003-09-30 devnull Write(1, c, strlen(c));
408 76193d7c 2003-09-30 devnull free(c);
409 76193d7c 2003-09-30 devnull p1 += np;
411 76193d7c 2003-09-30 devnull f->dot = addr;
412 76193d7c 2003-09-30 devnull return TRUE;
416 76193d7c 2003-09-30 devnull looper(File *f, Cmd *cp, int xy)
418 76193d7c 2003-09-30 devnull Posn p, op;
419 76193d7c 2003-09-30 devnull Range r;
421 76193d7c 2003-09-30 devnull r = addr.r;
422 76193d7c 2003-09-30 devnull op= xy? -1 : r.p1;
424 76193d7c 2003-09-30 devnull compile(cp->re);
425 76193d7c 2003-09-30 devnull for(p = r.p1; p<=r.p2; ){
426 76193d7c 2003-09-30 devnull if(!execute(f, p, r.p2)){ /* no match, but y should still run */
427 76193d7c 2003-09-30 devnull if(xy || op>r.p2)
429 76193d7c 2003-09-30 devnull f->dot.r.p1 = op, f->dot.r.p2 = r.p2;
430 76193d7c 2003-09-30 devnull p = r.p2+1; /* exit next loop */
432 76193d7c 2003-09-30 devnull if(sel.p[0].p1==sel.p[0].p2){ /* empty match? */
433 76193d7c 2003-09-30 devnull if(sel.p[0].p1==op){
435 76193d7c 2003-09-30 devnull continue;
437 76193d7c 2003-09-30 devnull p = sel.p[0].p2+1;
439 76193d7c 2003-09-30 devnull p = sel.p[0].p2;
441 76193d7c 2003-09-30 devnull f->dot.r = sel.p[0];
443 76193d7c 2003-09-30 devnull f->dot.r.p1 = op, f->dot.r.p2 = sel.p[0].p1;
445 76193d7c 2003-09-30 devnull op = sel.p[0].p2;
446 76193d7c 2003-09-30 devnull cmdexec(f, cp->ccmd);
447 76193d7c 2003-09-30 devnull compile(cp->re);
453 76193d7c 2003-09-30 devnull linelooper(File *f, Cmd *cp)
456 76193d7c 2003-09-30 devnull Range r, linesel;
457 76193d7c 2003-09-30 devnull Address a, a3;
460 76193d7c 2003-09-30 devnull r = addr.r;
461 76193d7c 2003-09-30 devnull a3.f = f;
462 76193d7c 2003-09-30 devnull a3.r.p1 = a3.r.p2 = r.p1;
463 76193d7c 2003-09-30 devnull for(p = r.p1; p<r.p2; p = a3.r.p2){
464 76193d7c 2003-09-30 devnull a3.r.p1 = a3.r.p2;
465 76193d7c 2003-09-30 devnull /*pjw if(p!=r.p1 || (linesel = lineaddr((Posn)0, a3, 1)).r.p2==p)*/
466 76193d7c 2003-09-30 devnull if(p!=r.p1 || (a = lineaddr((Posn)0, a3, 1), linesel = a.r, linesel.p2==p)){
467 76193d7c 2003-09-30 devnull a = lineaddr((Posn)1, a3, 1);
468 76193d7c 2003-09-30 devnull linesel = a.r;
470 76193d7c 2003-09-30 devnull if(linesel.p1 >= r.p2)
472 76193d7c 2003-09-30 devnull if(linesel.p2 >= r.p2)
473 76193d7c 2003-09-30 devnull linesel.p2 = r.p2;
474 76193d7c 2003-09-30 devnull if(linesel.p2 > linesel.p1)
475 76193d7c 2003-09-30 devnull if(linesel.p1>=a3.r.p2 && linesel.p2>a3.r.p2){
476 76193d7c 2003-09-30 devnull f->dot.r = linesel;
477 76193d7c 2003-09-30 devnull cmdexec(f, cp->ccmd);
478 76193d7c 2003-09-30 devnull a3.r = linesel;
479 76193d7c 2003-09-30 devnull continue;
487 76193d7c 2003-09-30 devnull filelooper(Cmd *cp, int XY)
489 76193d7c 2003-09-30 devnull File *f, *cur;
492 76193d7c 2003-09-30 devnull if(Glooping++)
493 76193d7c 2003-09-30 devnull error(EnestXY);
495 76193d7c 2003-09-30 devnull settempfile();
496 76193d7c 2003-09-30 devnull cur = curfile;
497 76193d7c 2003-09-30 devnull for(i = 0; i<tempfile.nused; i++){
498 76193d7c 2003-09-30 devnull f = tempfile.filepptr[i];
499 76193d7c 2003-09-30 devnull if(f==cmd)
500 76193d7c 2003-09-30 devnull continue;
501 76193d7c 2003-09-30 devnull if(cp->re==0 || filematch(f, cp->re)==XY)
502 76193d7c 2003-09-30 devnull cmdexec(f, cp->ccmd);
504 76193d7c 2003-09-30 devnull if(cur && whichmenu(cur)>=0) /* check that cur is still a file */
505 76193d7c 2003-09-30 devnull current(cur);
506 76193d7c 2003-09-30 devnull --Glooping;