|
|
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.