static void global(int sense, int query) { register char* s; register int c; register Line_t* a1; if (ed.global) error(2, "recursive global not allowed"); setwide(); squeeze(ed.dol > ed.zero); compile(); if (query) newline(); else { s = getrec(ed.buffer.global, '\n', REC_SPLICE|REC_TERMINATE); if (s[0] == '\n' && !s[1]) sfputr(ed.buffer.global, "p\n", 0); } for (a1 = ed.zero; a1 <= ed.dol; a1++) { a1->offset &= ~LINE_GLOBAL; if (a1 >= ed.addr1 && a1 <= ed.addr2 && execute(a1, 0) == sense) a1->offset |= LINE_GLOBAL; } /* special case: g/.../d (avoid n^2 algorithm) */ if (!query && s[0] == 'd' && s[1] == '\n' && !s[2]) gdelete(); else { for (a1 = ed.zero; a1 <= ed.dol; a1++) { if (a1->offset & LINE_GLOBAL) { a1->offset &= ~LINE_GLOBAL; ed.dot = a1; if (query) { putrec(lineget(a1->offset)); if ((c = getchr()) == EOF) break; else if (c == '\n') continue; else if (c == '&') { newline(); if (!*(ed.global = sfstrbase(ed.buffer.query))) error(2, "no saved command"); } else { ed.peekc = c; ed.global = getrec(ed.buffer.query, '\n', REC_TERMINATE); } } else ed.global = s; commands(); a1 = ed.zero; } } } }
void global(int k) { Rune *gp, globuf[GBSIZE]; int c, *a1; if(globp) error(Q); setwide(); squeeze(dol > zero); c = getchr(); if(c == '\n') error(Q); compile(c); gp = globuf; while((c=getchr()) != '\n') { if(c == EOF) error(Q); if(c == '\\') { c = getchr(); if(c != '\n') *gp++ = '\\'; } *gp++ = c; if(gp >= &globuf[GBSIZE-2]) error(Q); } if(gp == globuf) *gp++ = 'p'; *gp++ = '\n'; *gp = 0; for(a1=zero; a1<=dol; a1++) { *a1 &= ~01; if(a1 >= addr1 && a1 <= addr2 && match(a1) == k) *a1 |= 01; } /* * Special case: g/.../d (avoid n^2 algorithm) */ if(globuf[0] == 'd' && globuf[1] == '\n' && globuf[2] == 0) { gdelete(); return; } for(a1=zero; a1<=dol; a1++) { if(*a1 & 01) { *a1 &= ~01; dot = a1; globp = globuf; commands(); a1 = zero; } } }
void commands(void) { int *a1, c, temp; char lastsep; Dir *d; for(;;) { if(pflag) { pflag = 0; addr1 = addr2 = dot; printcom(); } c = '\n'; for(addr1 = 0;;) { lastsep = c; a1 = address(); c = getchr(); if(c != ',' && c != ';') break; if(lastsep == ',') error(Q); if(a1 == 0) { a1 = zero+1; if(a1 > dol) a1--; } addr1 = a1; if(c == ';') dot = a1; } if(lastsep != '\n' && a1 == 0) a1 = dol; if((addr2=a1) == 0) { given = 0; addr2 = dot; } else given = 1; if(addr1 == 0) addr1 = addr2; switch(c) { case 'a': add(0); continue; case 'b': nonzero(); browse(); continue; case 'c': nonzero(); newline(); rdelete(addr1, addr2); append(gettty, addr1-1); continue; case 'd': nonzero(); newline(); rdelete(addr1, addr2); continue; case 'E': fchange = 0; c = 'e'; case 'e': setnoaddr(); if(vflag && fchange) { fchange = 0; error(Q); } filename(c); init(); addr2 = zero; goto caseread; case 'f': setnoaddr(); filename(c); putst(savedfile); continue; case 'g': global(1); continue; case 'i': add(-1); continue; case 'j': if(!given) addr2++; newline(); join(); continue; case 'k': nonzero(); c = getchr(); if(c < 'a' || c > 'z') error(Q); newline(); names[c-'a'] = *addr2 & ~01; anymarks |= 01; continue; case 'm': move(0); continue; case 'n': listn++; newline(); printcom(); continue; case '\n': if(a1==0) { a1 = dot+1; addr2 = a1; addr1 = a1; } if(lastsep==';') addr1 = a1; printcom(); continue; case 'l': listf++; case 'p': case 'P': newline(); printcom(); continue; case 'Q': fchange = 0; case 'q': setnoaddr(); newline(); quit(); case 'r': filename(c); caseread: if((io=open(file, OREAD)) < 0) { lastc = '\n'; error(file); } if((d = dirfstat(io)) != nil){ if(d->mode & DMAPPEND) print("warning: %s is append only\n", file); free(d); } Binit(&iobuf, io, OREAD); setwide(); squeeze(0); c = zero != dol; append(getfile, addr2); exfile(OREAD); fchange = c; continue; case 's': nonzero(); substitute(globp != 0); continue; case 't': move(1); continue; case 'u': nonzero(); newline(); if((*addr2&~01) != subnewa) error(Q); *addr2 = subolda; dot = addr2; continue; case 'v': global(0); continue; case 'W': wrapp++; case 'w': setwide(); squeeze(dol>zero); temp = getchr(); if(temp != 'q' && temp != 'Q') { peekc = temp; temp = 0; } filename(c); if(!wrapp || ((io = open(file, OWRITE)) == -1) || ((seek(io, 0L, 2)) == -1)) if((io = create(file, OWRITE, 0666)) < 0) error(file); Binit(&iobuf, io, OWRITE); wrapp = 0; if(dol > zero) putfile(); exfile(OWRITE); if(addr1<=zero+1 && addr2==dol) fchange = 0; if(temp == 'Q') fchange = 0; if(temp) quit(); continue; case '=': setwide(); squeeze(0); newline(); count = addr2 - zero; putd(); putchr('\n'); continue; case '!': callunix(); continue; case EOF: return; } error(Q); } }
static void commands(void) { register Line_t* a1; register int c; register int n; char* s; int lastsep; for (;;) { trap(); if (ed.print & (REG_SUB_LIST|REG_SUB_NUMBER|REG_SUB_PRINT)) { ed.addr1 = ed.addr2 = ed.dot; print(); } if (!ed.global) { ed.evented = 0; if (ed.prompt > 0) sfputr(ed.msg, sfstrbase(ed.buffer.prompt), -1); } if ((c = getchr()) == ',' || c == ';') { ed.given = 1; ed.addr1 = (lastsep = c) == ',' ? ed.zero + 1 : ed.dot; a1 = ed.dol; c = getchr(); } else { ed.addr1 = 0; ed.peekc = c; c = '\n'; for (;;) { lastsep = c; a1 = address(); c = getchr(); if (c != ',' && c != ';') break; if (lastsep == ',') error(2, "invalid address"); if (!a1) { a1 = ed.zero + 1; if (a1 > ed.dol) a1--; } ed.addr1 = a1; if (c == ';') ed.dot = a1; } if (lastsep != '\n' && !a1) a1 = ed.dol; } if (!(ed.addr2 = a1)) { ed.given = 0; ed.addr2 = ed.dot; } else ed.given = 1; if (!ed.addr1) ed.addr1 = ed.addr2; switch (c) { case 'a': add(0); continue; case 'c': nonzero(); newline(); rdelete(ed.addr1, ed.addr2); append(getline, ed.addr1 - 1, NiL); continue; case 'd': nonzero(); newline(); rdelete(ed.addr1, ed.addr2); continue; case 'E': ed.modified = 0; c = 'e'; /*FALLTHROUGH*/ case 'e': setnoaddr(); if (ed.verbose && ed.modified) { ed.modified = 0; error(2, "modified data not written"); } /*FALLTHROUGH*/ case 'r': filename(c); setwide(); squeeze(0); c = ed.zero != ed.dol; append(getfile, ed.addr2, NiL); ed.modified = c; exfile(); continue; case 'f': setnoaddr(); filename(c); putrec(sfstrbase(ed.buffer.file)); continue; case 'G': global(1, 1); continue; case 'g': global(1, 0); continue; case 'H': ed.help = !ed.help; /*FALLTHROUGH*/ case 'h': setnoaddr(); newline(); if (ed.help || c == 'h') sfputr(ed.msg, sfstrbase(ed.buffer.help), '\n'); continue; case 'i': add(-1); continue; case 'j': if (!ed.given) ed.addr2++; newline(); join(); continue; case 'k': nonzero(); if ((c = getchr()) == EOF || (c -= MARK_MIN) < 0 || c >= elementsof(ed.marks)) error(2, "invalid mark"); newline(); ed.addr2->offset |= LINE_MARKED; ed.marks[c] = ed.addr2->offset & ~LINE_GLOBAL; ed.marked = 1; continue; case 'm': move(0); continue; case 'n': ed.print |= REG_SUB_NUMBER; newline(); print(); continue; case '\n': if (!a1) { a1 = ed.dot + 1; ed.addr2 = a1; ed.addr1 = a1; } if (lastsep == ';') ed.addr1 = a1; print(); continue; case 'l': ed.print |= REG_SUB_LIST; /*FALLTHROUGH*/ case 'p': newline(); print(); continue; case 'P': setnoaddr(); s = getrec(ed.buffer.line, '\n', 0); if (*s || !(ed.prompt = -ed.prompt) && (s = "*")) { sfstrseek(ed.buffer.prompt, 0, SEEK_SET); sfputr(ed.buffer.prompt, s, 0); ed.prompt = 1; } continue; case 'Q': ed.modified = 0; /*FALLTHROUGH*/ case 'q': setnoaddr(); newline(); quit(0); continue; case 'S': setnoaddr(); newline(); s = strchr(usage, '\n') + 5; sfprintf(ed.msg, "file=\"%s\"%s%s%s prompt=\"%s\" tmp=%lu%s event=%lu version=\"%-.*s\"\n", sfstrbase(ed.buffer.file), ed.modified ? " modified" : "", ed.help ? " help" : "", ed.verbose ? " verbose" : "", sfstrbase(ed.buffer.prompt), ed.tmpoff, ed.tmpoff > BLOCK_TMP ? "[file]" : "", ed.event, strchr(s, '\n') - s, s); continue; case 's': nonzero(); substitute(ed.global != 0); continue; case 't': move(1); continue; case 'u': setnoaddr(); newline(); undo(); continue; case 'V': global(0, 1); continue; case 'v': global(0, 0); continue; case 'W': case 'w': setwide(); squeeze(ed.dol > ed.zero); if ((n = getchr()) != 'q' && n != 'Q') { ed.peekc = n; n = 0; } filename(c); if (ed.dol > ed.zero) putfile(); exfile(); if (n == 'Q' || ed.addr1 <= ed.zero + 1 && ed.addr2 == ed.dol) ed.modified = 0; if (n) quit(0); continue; case 'z': nonzero(); page(); continue; case '=': setwide(); squeeze(0); newline(); sfprintf(ed.msg, "%d\n", ed.addr2 - ed.zero); continue; case '!': if (ed.restricted) error(2, "%c: restricted command", c); shell(); continue; case '#': setnoaddr(); getrec(ed.buffer.line, '\n', REC_IGNORE); continue; case EOF: return; } error(2, "unknown command"); } }