|
|
1.1 root 1: #include "sam.h"
2: #include "parse.h"
3:
4: #ifdef lint
5: #define UNUSED(c) NONEXISTENT((char *)c)
6: #else
7: #define UNUSED(c)
8: #endif
9:
10: int Glooping;
11: int nest;
12:
13: resetxec(){
14: Glooping=nest=0;
15: }
16: cmdexec(f, cp)
17: register File *f;
18: register Cmd *cp;
19: {
20: register i;
21: register Addr *ap;
22: Address a;
23: if(f && f->state==Unread)
24: load(f);
25: if(f==0 && (cp->addr==0 || cp->addr->type!='"') &&
26: !strchr("bBnqUXY!{", cp->cmdc) &&
27: cp->cmdc!=('c'|0x100) && !(cp->cmdc=='D' && cp->ctext))
28: error(Enofile);
29: i=lookup(cp->cmdc);
30: if(cmdtab[i].defaddr!=aNo){
31: if((ap=cp->addr)==0 && cp->cmdc!='\n'){
32: cp->addr=ap=newaddr();
33: ap->type='.';
34: if(cmdtab[i].defaddr==aAll)
35: ap->type='*';
36: }else if(ap && ap->type=='"' && ap->next==0 && cp->cmdc!='\n'){
37: ap->next=newaddr();
38: ap->next->type='.';
39: if(cmdtab[i].defaddr==aAll)
40: ap->next->type='*';
41: }
42: if(cp->addr){ /* may be false for '\n' (only) */
43: addr=address(ap, f->dot, 0);
44: f=addr.f;
45: }
46: }
47: current(f);
48: switch(cp->cmdc){
49: case '{':
50: a=cp->addr? address(cp->addr, f->dot, 0): f->dot;
51: for(cp=cp->ccmd; cp; cp=cp->next){
52: a.f->dot=a;
53: cmdexec(a.f, cp);
54: }
55: break;
56: default:
57: i=(*cmdtab[i].fn)(f, cp);
58: return i;
59: }
60: return 1;
61: }
62: a_cmd(f, cp)
63: File *f;
64: Cmd *cp;
65: {
66: return append(f, cp, addr.r.p2);
67: }
68: b_cmd(f, cp)
69: register File *f;
70: Cmd *cp;
71: {
72: extern File *tofile(), *getfile();
73: UNUSED(f);
74: f=cp->cmdc=='b'? tofile(cp->ctext) : getfile(cp->ctext);
75: if(f->state==Unread)
76: load(f);
77: else if(nest==0)
78: filename(f);
79: return TRUE;
80: }
81: c_cmd(f, cp)
82: register File *f;
83: Cmd *cp;
84: {
85: Fdelete(f, addr.r.p1, addr.r.p2);
86: f->dot.r.p1=f->dot.r.p2=addr.r.p2;
87: return append(f, cp, addr.r.p2);
88: }
89: d_cmd(f, cp)
90: File *f;
91: Cmd *cp;
92: {
93: UNUSED(cp);
94: Fdelete(f, addr.r.p1, addr.r.p2);
95: f->dot.r.p1=f->dot.r.p2=addr.r.p1;
96: return TRUE;
97: }
98: D_cmd(f, cp)
99: File *f;
100: Cmd *cp;
101: {
102: closefiles(f, cp->ctext);
103: return TRUE;
104: }
105: e_cmd(f, cp)
106: File *f;
107: Cmd *cp;
108: {
109: if(getname(f, cp->ctext, cp->cmdc=='e')==0)
110: error(Enoname);
111: edit(f, cp->cmdc);
112: return TRUE;
113: }
114: f_cmd(f, cp)
115: File *f;
116: Cmd *cp;
117: {
118: getname(f, cp->ctext, TRUE);
119: filename(f);
120: return TRUE;
121: }
122: g_cmd(f, cp)
123: File *f;
124: Cmd *cp;
125: {
126: if(f!=addr.f)panic("g_cmd f!=addr.f");
127: compile(cp->re);
128: if(execute(f, addr.r.p1, addr.r.p2) ^ cp->cmdc=='v'){
129: f->dot=addr;
130: return cmdexec(f, cp->ccmd);
131: }
132: return TRUE;
133: }
134: i_cmd(f, cp)
135: File *f;
136: Cmd *cp;
137: {
138: return append(f, cp, addr.r.p1);
139: }
140: k_cmd(f, cp)
141: File *f;
142: Cmd *cp;
143: {
144: UNUSED(cp);
145: f->mark=addr.r;
146: return TRUE;
147: }
148: m_cmd(f, cp)
149: register File *f;
150: register Cmd *cp;
151: {
152: Address addr2;
153: addr2=address(cp->caddr, f->dot, 0);
154: if(cp->cmdc=='m')
155: move(f, addr2);
156: else
157: copy(f, addr2);
158: current(addr2.f);
159: return TRUE;
160: }
161: n_cmd(f, cp)
162: File *f;
163: Cmd *cp;
164: {
165: register i;
166: UNUSED(f);
167: UNUSED(cp);
168: for(i=0; i<file.nused; i++){
169: if(file.ptr[i]==cmd)
170: continue;
171: strdupstr(&genstr, &file.ptr[i]->name);
172: filename(file.ptr[i]);
173: }
174: return TRUE;
175: }
176: p_cmd(f, cp)
177: File *f;
178: Cmd *cp;
179: {
180: UNUSED(cp);
181: return display(f);
182: }
183: q_cmd(f, cp)
184: File *f;
185: Cmd *cp;
186: {
187: UNUSED(cp);
188: UNUSED(f);
189: trytoquit();
190: if(downloaded){
191: outT0(Hexit);
192: return TRUE;
193: }
194: return FALSE;
195: }
196: s_cmd(f, cp)
197: register File *f;
198: register Cmd *cp;
199: {
200: register i, c, n;
201: register Posn p1, op, didsub=0, delta=0;
202: n=cp->num;
203: op= -1;
204: compile(cp->re);
205: for(p1=addr.r.p1; p1<=addr.r.p2 && execute(f, p1, addr.r.p2); ){
206: if(sel.p1==sel.p2){ /* empty match? */
207: if(sel.p1==op){
208: p1++;
209: continue;
210: }
211: p1=sel.p2+1;
212: }else
213: p1=sel.p2;
214: op=sel.p2;
215: if(--n>0)
216: continue;
217: strzero(&genstr);
218: for(i=0; i<cp->ctext->n; i++)
219: if((c=cp->ctext->s[i])=='\\' && i<cp->ctext->n-1)
220: straddc(&genstr, cp->ctext->s[++i]);
221: else if(c!='&')
222: straddc(&genstr, c);
223: else{
224: if(sel.p2-sel.p1>BLOCKSIZE)
225: error(Elongrhs);
226: Fchars(f, genbuf, sel.p1, sel.p2);
227: strinsert(&genstr,
228: tempstr(genbuf, (int)(sel.p2-sel.p1)),
229: (ulong)genstr.n);
230: }
231: if(sel.p1!=sel.p2){
232: Fdelete(f, sel.p1, sel.p2);
233: delta-=sel.p2-sel.p1;
234: }
235: if(genstr.n){
236: Finsert(f, &genstr, sel.p2);
237: delta+=genstr.n;
238: }
239: didsub=1;
240: if(!cp->flag)
241: break;
242: }
243: if(!didsub && nest==0)
244: error(Enosub);
245: f->dot.r.p1=addr.r.p1, f->dot.r.p2=addr.r.p2+delta;
246: return TRUE;
247: }
248: u_cmd(f, cp)
249: File *f;
250: Cmd *cp;
251: {
252: register n;
253: UNUSED(f);
254: UNUSED(cp);
255: n=cp->num;
256: while(n--)
257: undo();
258: return TRUE;
259: }
260: w_cmd(f, cp)
261: File *f;
262: Cmd *cp;
263: {
264: if(getname(f, cp->ctext, FALSE)==0)
265: error(Enoname);
266: writef(f);
267: return TRUE;
268: }
269: x_cmd(f, cp)
270: File *f;
271: Cmd *cp;
272: {
273: if(cp->re)
274: looper(f, cp, cp->cmdc=='x');
275: else
276: linelooper(f, cp);
277: return TRUE;
278: }
279: X_cmd(f, cp)
280: File *f;
281: Cmd *cp;
282: {
283: UNUSED(f);
284: filelooper(cp, cp->cmdc=='X');
285: return TRUE;
286: }
287: unix_cmd(f, cp)
288: File *f;
289: Cmd *cp;
290: {
291: Unix(f, cp->cmdc, cp->ctext, nest);
292: return TRUE;
293: }
294: eq_cmd(f, cp)
295: File *f;
296: Cmd *cp;
297: {
298: register charsonly;
299: switch(cp->ctext->n){
300: case 1:
301: charsonly=FALSE;
302: break;
303: case 2:
304: if(cp->ctext->s[0]=='#'){
305: charsonly=TRUE;
306: break;
307: }
308: default:
309: error(Enewline);
310: }
311: printposn(f, charsonly);
312: return TRUE;
313: }
314: nl_cmd(f, cp)
315: register File *f;
316: register Cmd *cp;
317: {
318: register Address ad; /* SUN fix */
319: if(cp->addr==0){
320: /* First put it on newline boundaries */
321: addr=lineaddr((Posn)0, f->dot, -1);
322: ad=lineaddr((Posn)0, f->dot, 1);
323: addr.r.p2=ad.r.p2;
324: if(addr.r.p1==f->dot.r.p1 && addr.r.p2==f->dot.r.p2)
325: addr=lineaddr((Posn)1, f->dot, 1);
326: display(f);
327: }else if(downloaded)
328: moveto(f, addr.r);
329: else
330: display(f);
331: return TRUE;
332: }
333: cd_cmd(f, cp)
334: register File *f;
335: register Cmd *cp;
336: {
337: UNUSED(f);
338: cd(cp->ctext);
339: return TRUE;
340: }
341: append(f, cp, p)
342: register File *f;
343: register Cmd *cp;
344: register Posn p;
345: {
346: if(cp->ctext->n>0 && cp->ctext->s[cp->ctext->n-1]==0)
347: --cp->ctext->n;
348: if(cp->ctext->n>0)
349: Finsert(f, cp->ctext, p);
350: f->dot.r.p1=p;
351: f->dot.r.p2=p+cp->ctext->n;
352: return TRUE;
353: }
354: display(f)
355: register File *f;
356: {
357: register Posn p1=addr.r.p1, p2=addr.r.p2;
358: register np, n;
359: if(f!=addr.f)panic("display f!=addr.f");
360: while(p1<p2){
361: np=p2-p1;
362: if(np>BLOCKSIZE)
363: np=BLOCKSIZE;
364: n=Fchars(f, genbuf, p1, p1+np);
365: if(n<=0)
366: panic("display");
367: if(downloaded)
368: termwrite(genbuf, n);
369: else
370: Write(1, genbuf, n);
371: p1+=n;
372: }
373: f->dot=addr;
374: return TRUE;
375: }
376: looper(f, cp, xy)
377: register File *f;
378: register Cmd *cp;
379: {
380: register Posn p, op;
381: Range r;
382: r=addr.r;
383: op= xy? -1 : r.p1;
384: nest++;
385: compile(cp->re);
386: for(p=r.p1; p<=r.p2; ){
387: if(!execute(f, p, r.p2)){ /* no match, but y should still run */
388: if(xy || op>r.p2)
389: break;
390: f->dot.r.p1=op, f->dot.r.p2=r.p2;
391: p=r.p2+1; /* exit next loop */
392: }else{
393: if(sel.p1==sel.p2){ /* empty match? */
394: if(sel.p1==op){
395: p++;
396: continue;
397: }
398: p=sel.p2+1;
399: }else
400: p=sel.p2;
401: if(xy)
402: f->dot.r=sel;
403: else
404: f->dot.r.p1=op, f->dot.r.p2=sel.p1;
405: }
406: op=sel.p2;
407: cmdexec(f, cp->ccmd);
408: compile(cp->re);
409: }
410: --nest;
411: }
412: linelooper(f, cp)
413: register File *f;
414: register Cmd *cp;
415: {
416: register Posn p;
417: Range r, linesel;
418: Address a3, ad; /* SUN fix */
419: nest++;
420: r=addr.r;
421: a3.f=f;
422: a3.r.p1=a3.r.p2=r.p1;
423: for(p=r.p1; p<r.p2; p=a3.r.p2){
424: a3.r.p1=a3.r.p2;
425: /*pjw if(p!=r.p1 || (linesel=lineaddr((Posn)0, a3, 1)).r.p2==p)*/
426: if(p!=r.p1 || ((ad=lineaddr((Posn)0, a3, 1)), (linesel=ad.r), linesel.p2==p))
427: ad=lineaddr((Posn)1, a3, 1), linesel=ad.r;
428: if(linesel.p1>=r.p2)
429: break;
430: if(linesel.p2>=r.p2)
431: linesel.p2=r.p2;
432: if(linesel.p2>linesel.p1)
433: if(linesel.p1>=a3.r.p2 && linesel.p2>a3.r.p2){
434: f->dot.r=linesel;
435: cmdexec(f, cp->ccmd);
436: a3.r=linesel;
437: continue;
438: }
439: break;
440: }
441: --nest;
442: }
443: filelooper(cp, XY)
444: register Cmd *cp;
445: {
446: register File *f, *cur;
447: register i;
448: if(Glooping++)
449: error(EnestXY);
450: nest++;
451: settempfile();
452: cur=curfile;
453: for(i=0; i<tempfile.nused; i++){
454: f=tempfile.ptr[i];
455: if(f==cmd)
456: continue;
457: if(cp->re==0 || filematch(f, cp->re)==XY)
458: cmdexec(f, cp->ccmd);
459: }
460: if(cur && whichmenu(cur)>=0) /* check that cur is still a file */
461: current(cur);
462: --Glooping;
463: --nest;
464: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.