7 int append(File*, Cmd*, Posn);
9 void looper(File*, Cmd*, int);
10 void filelooper(Cmd*, int);
11 void linelooper(File*, Cmd*);
20 cmdexec(File *f, Cmd *cp)
28 if(f==0 && (cp->addr==0 || cp->addr->type!='"') &&
29 !utfrune("bBnqUXY!", cp->cmdc) &&
30 cp->cmdc!=('c'|0x100) && !(cp->cmdc=='D' && cp->ctext))
33 if(i >= 0 && cmdtab[i].defaddr != aNo){
34 if((ap=cp->addr)==0 && cp->cmdc!='\n'){
35 cp->addr = ap = newaddr();
37 if(cmdtab[i].defaddr == aAll)
39 }else if(ap && ap->type=='"' && ap->next==0 && cp->cmdc!='\n'){
42 if(cmdtab[i].defaddr == aAll)
45 if(cp->addr){ /* may be false for '\n' (only) */
46 static Address none = {0,0,0};
48 addr = address(ap, f->dot, 0);
50 addr = address(ap, none, 0);
57 a = cp->addr? address(cp->addr, f->dot, 0): f->dot;
58 for(cp = cp->ccmd; cp; cp = cp->next){
64 i=(*cmdtab[i].fn)(f, cp);
72 a_cmd(File *f, Cmd *cp)
74 return append(f, cp, addr.r.p2);
78 b_cmd(File *f, Cmd *cp)
81 f = cp->cmdc=='b'? tofile(cp->ctext) : getfile(cp->ctext);
90 c_cmd(File *f, Cmd *cp)
92 logdelete(f, addr.r.p1, addr.r.p2);
93 f->ndot.r.p1 = f->ndot.r.p2 = addr.r.p2;
94 return append(f, cp, addr.r.p2);
98 d_cmd(File *f, Cmd *cp)
101 logdelete(f, addr.r.p1, addr.r.p2);
102 f->ndot.r.p1 = f->ndot.r.p2 = addr.r.p1;
107 D_cmd(File *f, Cmd *cp)
109 closefiles(f, cp->ctext);
114 e_cmd(File *f, Cmd *cp)
116 if(getname(f, cp->ctext, cp->cmdc=='e')==0)
123 f_cmd(File *f, Cmd *cp)
125 getname(f, cp->ctext, TRUE);
131 g_cmd(File *f, Cmd *cp)
133 if(f!=addr.f)panic("g_cmd f!=addr.f");
135 if(execute(f, addr.r.p1, addr.r.p2) ^ cp->cmdc=='v'){
137 return cmdexec(f, cp->ccmd);
143 i_cmd(File *f, Cmd *cp)
145 return append(f, cp, addr.r.p1);
149 k_cmd(File *f, Cmd *cp)
157 m_cmd(File *f, Cmd *cp)
161 addr2 = address(cp->caddr, f->dot, 0);
170 n_cmd(File *f, Cmd *cp)
175 for(i = 0; i<file.nused; i++){
176 if(file.filepptr[i] == cmd)
178 f = file.filepptr[i];
179 Strduplstr(&genstr, &f->name);
186 p_cmd(File *f, Cmd *cp)
193 q_cmd(File *f, Cmd *cp)
206 s_cmd(File *f, Cmd *cp)
209 Posn p1, op, didsub = 0, delta = 0;
214 for(p1 = addr.r.p1; p1<=addr.r.p2 && execute(f, p1, addr.r.p2); ){
215 if(sel.p[0].p1==sel.p[0].p2){ /* empty match? */
227 for(i = 0; i<cp->ctext->n; i++)
228 if((c = cp->ctext->s[i])=='\\' && i<cp->ctext->n-1){
229 c = cp->ctext->s[++i];
230 if('1'<=c && c<='9') {
232 if(sel.p[j].p2-sel.p[j].p1>BLOCKSIZE)
234 bufread(f, sel.p[j].p1, genbuf, sel.p[j].p2-sel.p[j].p1);
235 Strinsert(&genstr, tmprstr(genbuf, (sel.p[j].p2-sel.p[j].p1)), genstr.n);
241 if(sel.p[0].p2-sel.p[0].p1>BLOCKSIZE)
243 bufread(f, sel.p[0].p1, genbuf, sel.p[0].p2-sel.p[0].p1);
245 tmprstr(genbuf, (int)(sel.p[0].p2-sel.p[0].p1)),
248 if(sel.p[0].p1!=sel.p[0].p2){
249 logdelete(f, sel.p[0].p1, sel.p[0].p2);
250 delta-=sel.p[0].p2-sel.p[0].p1;
253 loginsert(f, sel.p[0].p2, genstr.s, genstr.n);
260 if(!didsub && nest==0)
262 f->ndot.r.p1 = addr.r.p1, f->ndot.r.p2 = addr.r.p2+delta;
267 u_cmd(File *f, Cmd *cp)
275 while(n-- && undo(TRUE))
278 while(n++ && undo(FALSE))
284 w_cmd(File *f, Cmd *cp)
289 if(getname(f, cp->ctext, FALSE)==0)
292 error_s(Ewseq, genc);
298 x_cmd(File *f, Cmd *cp)
301 looper(f, cp, cp->cmdc=='x');
308 X_cmd(File *f, Cmd *cp)
311 filelooper(cp, cp->cmdc=='X');
316 plan9_cmd(File *f, Cmd *cp)
318 plan9(f, cp->cmdc, cp->ctext, nest);
323 eq_cmd(File *f, Cmd *cp)
327 switch(cp->ctext->n){
332 if(cp->ctext->s[0]=='#'){
340 printposn(f, charsonly);
345 nl_cmd(File *f, Cmd *cp)
350 /* First put it on newline boundaries */
351 addr = lineaddr((Posn)0, f->dot, -1);
352 a = lineaddr((Posn)0, f->dot, 1);
354 if(addr.r.p1==f->dot.r.p1 && addr.r.p2==f->dot.r.p2)
355 addr = lineaddr((Posn)1, f->dot, 1);
365 cd_cmd(File *f, Cmd *cp)
373 append(File *f, Cmd *cp, Posn p)
375 if(cp->ctext->n>0 && cp->ctext->s[cp->ctext->n-1]==0)
378 loginsert(f, p, cp->ctext->s, cp->ctext->n);
380 f->ndot.r.p2 = p+cp->ctext->n;
394 fprint(2, "bad display addr p1=%ld p2=%ld f->nc=%d\n", p1, p2, f->nc); /*ZZZ should never happen, can remove */
401 bufread(f, p1, genbuf, np);
403 c = Strtoc(tmprstr(genbuf, np+1));
407 Write(1, c, strlen(c));
416 looper(File *f, Cmd *cp, int xy)
425 for(p = r.p1; p<=r.p2; ){
426 if(!execute(f, p, r.p2)){ /* no match, but y should still run */
429 f->dot.r.p1 = op, f->dot.r.p2 = r.p2;
430 p = r.p2+1; /* exit next loop */
432 if(sel.p[0].p1==sel.p[0].p2){ /* empty match? */
443 f->dot.r.p1 = op, f->dot.r.p2 = sel.p[0].p1;
446 cmdexec(f, cp->ccmd);
453 linelooper(File *f, Cmd *cp)
462 a3.r.p1 = a3.r.p2 = r.p1;
463 for(p = r.p1; p<r.p2; p = a3.r.p2){
465 /*pjw if(p!=r.p1 || (linesel = lineaddr((Posn)0, a3, 1)).r.p2==p)*/
466 if(p!=r.p1 || (a = lineaddr((Posn)0, a3, 1), linesel = a.r, linesel.p2==p)){
467 a = lineaddr((Posn)1, a3, 1);
470 if(linesel.p1 >= r.p2)
472 if(linesel.p2 >= r.p2)
474 if(linesel.p2 > linesel.p1)
475 if(linesel.p1>=a3.r.p2 && linesel.p2>a3.r.p2){
477 cmdexec(f, cp->ccmd);
487 filelooper(Cmd *cp, int XY)
497 for(i = 0; i<tempfile.nused; i++){
498 f = tempfile.filepptr[i];
501 if(cp->re==0 || filematch(f, cp->re)==XY)
502 cmdexec(f, cp->ccmd);
504 if(cur && whichmenu(cur)>=0) /* check that cur is still a file */