summaryrefslogtreecommitdiff
path: root/sys/src/ape/cmd/sed/sed1.c
diff options
context:
space:
mode:
authorTaru Karttunen <taruti@taruti.net>2011-03-30 15:46:40 +0300
committerTaru Karttunen <taruti@taruti.net>2011-03-30 15:46:40 +0300
commite5888a1ffdae813d7575f5fb02275c6bb07e5199 (patch)
treed8d51eac403f07814b9e936eed0c9a79195e2450 /sys/src/ape/cmd/sed/sed1.c
Import sources from 2011-03-30 iso image
Diffstat (limited to 'sys/src/ape/cmd/sed/sed1.c')
-rwxr-xr-xsys/src/ape/cmd/sed/sed1.c719
1 files changed, 719 insertions, 0 deletions
diff --git a/sys/src/ape/cmd/sed/sed1.c b/sys/src/ape/cmd/sed/sed1.c
new file mode 100755
index 000000000..131e0e8a5
--- /dev/null
+++ b/sys/src/ape/cmd/sed/sed1.c
@@ -0,0 +1,719 @@
+#include <stdlib.h>
+#include <sys/types.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <stdio.h>
+#include "sed.h"
+
+#define Read(f, buf, n) (fflush(stdout), read(f, buf, n))
+
+void
+execute(uchar *file)
+{
+ uchar *p1, *p2;
+ union reptr *ipc;
+ int c;
+ long l;
+ uchar *execp;
+
+ if (file) {
+ if ((f = open((char*)file, O_RDONLY)) < 0) {
+ fprintf(stderr, "sed: Can't open %s\n", file);
+ }
+ } else
+ f = 0;
+
+ ebp = ibuf;
+ cbp = ibuf;
+
+ if(pending) {
+ ipc = pending;
+ pending = 0;
+ goto yes;
+ }
+
+ for(;;) {
+ if((execp = gline(linebuf)) == badp) {
+ close(f);
+ return;
+ }
+ spend = execp;
+
+ for(ipc = ptrspace; ipc->r1.command; ) {
+
+ p1 = ipc->r1.ad1;
+ p2 = ipc->r1.ad2;
+
+ if(p1) {
+
+ if(ipc->r1.inar) {
+ if(*p2 == CEND) {
+ p1 = 0;
+ } else if(*p2 == CLNUM) {
+ l = p2[1]&0377
+ | ((p2[2]&0377)<<8)
+ | ((p2[3]&0377)<<16)
+ | ((p2[4]&0377)<<24);
+ if(lnum > l) {
+ ipc->r1.inar = 0;
+ if(ipc->r1.negfl)
+ goto yes;
+ ipc++;
+ continue;
+ }
+ if(lnum == l) {
+ ipc->r1.inar = 0;
+ }
+ } else if(match(p2, 0)) {
+ ipc->r1.inar = 0;
+ }
+ } else if(*p1 == CEND) {
+ if(!dolflag) {
+ if(ipc->r1.negfl)
+ goto yes;
+ ipc++;
+ continue;
+ }
+
+ } else if(*p1 == CLNUM) {
+ l = p1[1]&0377
+ | ((p1[2]&0377)<<8)
+ | ((p1[3]&0377)<<16)
+ | ((p1[4]&0377)<<24);
+ if(lnum != l) {
+ if(ipc->r1.negfl)
+ goto yes;
+ ipc++;
+ continue;
+ }
+ if(p2)
+ ipc->r1.inar = 1;
+ } else if(match(p1, 0)) {
+ if(p2)
+ ipc->r1.inar = 1;
+ } else {
+ if(ipc->r1.negfl)
+ goto yes;
+ ipc++;
+ continue;
+ }
+ }
+
+ if(ipc->r1.negfl) {
+ ipc++;
+ continue;
+ }
+ yes:
+ command(ipc);
+
+ if(delflag)
+ break;
+
+ if(jflag) {
+ jflag = 0;
+ if((ipc = ipc->r2.lb1) == 0) {
+ ipc = ptrspace;
+ break;
+ }
+ } else
+ ipc++;
+
+ }
+ if(!nflag && !delflag) {
+ for(p1 = linebuf; p1 < spend; p1++)
+ putc(*p1, stdout);
+ putc('\n', stdout);
+ }
+
+ if(aptr > abuf) {
+ arout();
+ }
+
+ delflag = 0;
+
+ }
+}
+int
+match(uchar *expbuf, int gf)
+{
+ uchar *p1, *p2;
+ int c;
+
+ if(gf) {
+ if(*expbuf) return(0);
+ p1 = linebuf;
+ p2 = genbuf;
+ while(*p1++ = *p2++);
+ locs = p1 = loc2;
+ } else {
+ p1 = linebuf;
+ locs = 0;
+ }
+
+ p2 = expbuf;
+ if(*p2++) {
+ loc1 = p1;
+ if(*p2 == CCHR && p2[1] != *p1)
+ return(0);
+ return(advance(p1, p2));
+ }
+
+ /* fast check for first character */
+
+ if(*p2 == CCHR) {
+ c = p2[1];
+ do {
+ if(*p1 != c)
+ continue;
+ if(advance(p1, p2)) {
+ loc1 = p1;
+ return(1);
+ }
+ } while(*p1++);
+ return(0);
+ }
+
+ do {
+ if(advance(p1, p2)) {
+ loc1 = p1;
+ return(1);
+ }
+ } while(*p1++);
+ return(0);
+}
+int
+advance(uchar *alp, uchar *aep)
+{
+ uchar *lp, *ep, *curlp;
+ uchar c;
+ uchar *bbeg;
+ int ct;
+
+/*fprintf(stderr, "*lp = %c, %o\n*ep = %c, %o\n", *lp, *lp, *ep, *ep); /*DEBUG*/
+
+ lp = alp;
+ ep = aep;
+ for (;;) switch (*ep++) {
+
+ case CCHR:
+ if (*ep++ == *lp++)
+ continue;
+ return(0);
+
+ case CDOT:
+ if (*lp++)
+ continue;
+ return(0);
+
+ case CNL:
+ case CDOL:
+ if (*lp == 0)
+ continue;
+ return(0);
+
+ case CEOF:
+ loc2 = lp;
+ return(1);
+
+ case CCL:
+ c = *lp++;
+ if(ep[c>>3] & bittab[c & 07]) {
+ ep += 32;
+ continue;
+ }
+ return(0);
+
+ case CBRA:
+ braslist[*ep++] = lp;
+ continue;
+
+ case CKET:
+ braelist[*ep++] = lp;
+ continue;
+
+ case CBACK:
+ bbeg = braslist[*ep];
+ ct = braelist[*ep++] - bbeg;
+
+ if(ecmp(bbeg, lp, ct)) {
+ lp += ct;
+ continue;
+ }
+ return(0);
+
+ case CBACK|STAR:
+ bbeg = braslist[*ep];
+ ct = braelist[*ep++] - bbeg;
+ curlp = lp;
+ while(ecmp(bbeg, lp, ct))
+ lp += ct;
+
+ while(lp >= curlp) {
+ if(advance(lp, ep)) return(1);
+ lp -= ct;
+ }
+ return(0);
+
+
+ case CDOT|STAR:
+ curlp = lp;
+ while (*lp++);
+ goto star;
+
+ case CCHR|STAR:
+ curlp = lp;
+ while (*lp++ == *ep);
+ ep++;
+ goto star;
+
+ case CCL|STAR:
+ curlp = lp;
+ do {
+ c = *lp++;
+ } while(ep[c>>3] & bittab[c & 07]);
+ ep += 32;
+ goto star;
+
+ star:
+ if(--lp == curlp) {
+ continue;
+ }
+
+ if(*ep == CCHR) {
+ c = ep[1];
+ do {
+ if(*lp != c)
+ continue;
+ if(advance(lp, ep))
+ return(1);
+ } while(lp-- > curlp);
+ return(0);
+ }
+
+ if(*ep == CBACK) {
+ c = *(braslist[ep[1]]);
+ do {
+ if(*lp != c)
+ continue;
+ if(advance(lp, ep))
+ return(1);
+ } while(lp-- > curlp);
+ return(0);
+ }
+
+ do {
+ if(lp == locs) break;
+ if (advance(lp, ep))
+ return(1);
+ } while (lp-- > curlp);
+ return(0);
+
+ default:
+ fprintf(stderr, "sed: RE botch, %o\n", *--ep);
+ exit(1);
+ }
+}
+int
+substitute(union reptr *ipc)
+{
+ uchar *oloc2;
+
+ if(match(ipc->r1.re1, 0)) {
+
+ sflag = 1;
+ if(!ipc->r1.gfl) {
+ dosub(ipc->r1.rhs);
+ return(1);
+ }
+
+ oloc2 = NULL;
+ do {
+ if(oloc2 == loc2) {
+ loc2++;
+ continue;
+ } else {
+ dosub(ipc->r1.rhs);
+ if(*loc2 == 0)
+ break;
+ oloc2 = loc2;
+ }
+ } while(match(ipc->r1.re1, 1));
+ return(1);
+ }
+ return(0);
+}
+
+void
+dosub(uchar *rhsbuf)
+{
+ uchar *lp, *sp, *rp;
+ int c;
+
+ lp = linebuf;
+ sp = genbuf;
+ rp = rhsbuf;
+ while (lp < loc1)
+ *sp++ = *lp++;
+ while(c = *rp++) {
+ if (c == '\\') {
+ c = *rp++;
+ if (c >= '1' && c < NBRA+'1') {
+ sp = place(sp, braslist[c-'1'], braelist[c-'1']);
+ continue;
+ }
+ } else if(c == '&') {
+ sp = place(sp, loc1, loc2);
+ continue;
+ }
+ *sp++ = c;
+ if (sp >= &genbuf[LBSIZE])
+ fprintf(stderr, "sed: Output line too long.\n");
+ }
+ lp = loc2;
+ loc2 = sp - genbuf + linebuf;
+ while (*sp++ = *lp++)
+ if (sp >= &genbuf[LBSIZE]) {
+ fprintf(stderr, "sed: Output line too long.\n");
+ }
+ lp = linebuf;
+ sp = genbuf;
+ while (*lp++ = *sp++);
+ spend = lp-1;
+}
+uchar *
+place(uchar *asp, uchar *al1, uchar *al2)
+{
+ uchar *sp, *l1, *l2;
+
+ sp = asp;
+ l1 = al1;
+ l2 = al2;
+ while (l1 < l2) {
+ *sp++ = *l1++;
+ if (sp >= &genbuf[LBSIZE])
+ fprintf(stderr, "sed: Output line too long.\n");
+ }
+ return(sp);
+}
+
+void
+command(union reptr *ipc)
+{
+ int i;
+ uchar *p1, *p2;
+ uchar *execp;
+
+
+ switch(ipc->r1.command) {
+
+ case ACOM:
+ *aptr++ = ipc;
+ if(aptr >= &abuf[ABUFSIZE]) {
+ fprintf(stderr, "sed: Too many appends after line %ld\n",
+ lnum);
+ }
+ *aptr = 0;
+ break;
+
+ case CCOM:
+ delflag = 1;
+ if(!ipc->r1.inar || dolflag) {
+ for(p1 = ipc->r1.re1; *p1; )
+ putc(*p1++, stdout);
+ putc('\n', stdout);
+ }
+ break;
+ case DCOM:
+ delflag++;
+ break;
+ case CDCOM:
+ p1 = p2 = linebuf;
+
+ while(*p1 != '\n') {
+ if(*p1++ == 0) {
+ delflag++;
+ return;
+ }
+ }
+
+ p1++;
+ while(*p2++ = *p1++);
+ spend = p2-1;
+ jflag++;
+ break;
+
+ case EQCOM:
+ fprintf(stdout, "%ld\n", lnum);
+ break;
+
+ case GCOM:
+ p1 = linebuf;
+ p2 = holdsp;
+ while(*p1++ = *p2++);
+ spend = p1-1;
+ break;
+
+ case CGCOM:
+ *spend++ = '\n';
+ p1 = spend;
+ p2 = holdsp;
+ while(*p1++ = *p2++)
+ if(p1 >= lbend)
+ break;
+ spend = p1-1;
+ break;
+
+ case HCOM:
+ p1 = holdsp;
+ p2 = linebuf;
+ while(*p1++ = *p2++);
+ hspend = p1-1;
+ break;
+
+ case CHCOM:
+ *hspend++ = '\n';
+ p1 = hspend;
+ p2 = linebuf;
+ while(*p1++ = *p2++)
+ if(p1 >= hend)
+ break;
+ hspend = p1-1;
+ break;
+
+ case ICOM:
+ for(p1 = ipc->r1.re1; *p1; )
+ putc(*p1++, stdout);
+ putc('\n', stdout);
+ break;
+
+ case BCOM:
+ jflag = 1;
+ break;
+
+ case LCOM:
+ p1 = linebuf;
+ p2 = genbuf;
+ while(*p1) {
+ p2 = lformat(*p1++ & 0377, p2);
+ if(p2>lcomend && *p1) {
+ *p2 = 0;
+ fprintf(stdout, "%s\\\n", genbuf);
+ p2 = genbuf;
+ }
+ }
+ if(p2>genbuf && (p1[-1]==' '||p1[-1]=='\n'))
+ p2 = lformat('\n', p2);
+ *p2 = 0;
+ fprintf(stdout, "%s\n", genbuf);
+ break;
+
+ case NCOM:
+ if(!nflag) {
+ for(p1 = linebuf; p1 < spend; p1++)
+ putc(*p1, stdout);
+ putc('\n', stdout);
+ }
+
+ if(aptr > abuf)
+ arout();
+ if((execp = gline(linebuf)) == badp) {
+ pending = ipc;
+ delflag = 1;
+ break;
+ }
+ spend = execp;
+
+ break;
+ case CNCOM:
+ if(aptr > abuf)
+ arout();
+ *spend++ = '\n';
+ if((execp = gline(spend)) == badp) {
+ pending = ipc;
+ delflag = 1;
+ break;
+ }
+ spend = execp;
+ break;
+
+ case PCOM:
+ for(p1 = linebuf; p1 < spend; p1++)
+ putc(*p1, stdout);
+ putc('\n', stdout);
+ break;
+ case CPCOM:
+ cpcom:
+ for(p1 = linebuf; *p1 != '\n' && *p1 != '\0'; )
+ putc(*p1++, stdout);
+ putc('\n', stdout);
+ break;
+
+ case QCOM:
+ if(!nflag) {
+ for(p1 = linebuf; p1 < spend; p1++)
+ putc(*p1, stdout);
+ putc('\n', stdout);
+ }
+ if(aptr > abuf) arout();
+ fclose(stdout);
+ lseek(f,(long)(cbp-ebp),2);
+ exit(0);
+ case RCOM:
+
+ *aptr++ = ipc;
+ if(aptr >= &abuf[ABUFSIZE])
+ fprintf(stderr, "sed: Too many reads after line%ld\n",
+ lnum);
+
+ *aptr = 0;
+
+ break;
+
+ case SCOM:
+ i = substitute(ipc);
+ if(ipc->r1.pfl && i)
+ if(ipc->r1.pfl == 1) {
+ for(p1 = linebuf; p1 < spend; p1++)
+ putc(*p1, stdout);
+ putc('\n', stdout);
+ }
+ else
+ goto cpcom;
+ if(i && ipc->r1.fcode)
+ goto wcom;
+ break;
+
+ case TCOM:
+ if(sflag == 0) break;
+ sflag = 0;
+ jflag = 1;
+ break;
+
+ wcom:
+ case WCOM:
+ fprintf(ipc->r1.fcode, "%s\n", linebuf);
+ fflush(ipc->r1.fcode);
+ break;
+ case XCOM:
+ p1 = linebuf;
+ p2 = genbuf;
+ while(*p2++ = *p1++);
+ p1 = holdsp;
+ p2 = linebuf;
+ while(*p2++ = *p1++);
+ spend = p2 - 1;
+ p1 = genbuf;
+ p2 = holdsp;
+ while(*p2++ = *p1++);
+ hspend = p2 - 1;
+ break;
+
+ case YCOM:
+ p1 = linebuf;
+ p2 = ipc->r1.re1;
+ while(*p1 = p2[*p1]) p1++;
+ break;
+ }
+
+}
+
+uchar *
+gline(uchar *addr)
+{
+ uchar *p1, *p2;
+ int c;
+ sflag = 0;
+ p1 = addr;
+ p2 = cbp;
+ for (;;) {
+ if (p2 >= ebp) {
+ if ((c = Read(f, ibuf, 512)) <= 0) {
+ return(badp);
+ }
+ p2 = ibuf;
+ ebp = ibuf+c;
+ }
+ if ((c = *p2++) == '\n') {
+ if(p2 >= ebp) {
+ if((c = Read(f, ibuf, 512)) <= 0) {
+ close(f);
+ if(eargc == 0)
+ dolflag = 1;
+ }
+
+ p2 = ibuf;
+ ebp = ibuf + c;
+ }
+ break;
+ }
+ if(c)
+ if(p1 < lbend)
+ *p1++ = c;
+ }
+ lnum++;
+ *p1 = 0;
+ cbp = p2;
+
+ return(p1);
+}
+int
+ecmp(uchar *a, uchar *b, int count)
+{
+ while(count--)
+ if(*a++ != *b++) return(0);
+ return(1);
+}
+
+void
+arout(void)
+{
+ uchar *p1;
+ FILE *fi;
+ uchar c;
+ int t;
+
+ aptr = abuf - 1;
+ while(*++aptr) {
+ if((*aptr)->r1.command == ACOM) {
+ for(p1 = (*aptr)->r1.re1; *p1; )
+ putc(*p1++, stdout);
+ putc('\n', stdout);
+ } else {
+ if((fi = fopen((char*)((*aptr)->r1.re1), "r")) == NULL)
+ continue;
+ while((t = getc(fi)) != EOF) {
+ c = t;
+ putc(c, stdout);
+ }
+ fclose(fi);
+ }
+ }
+ aptr = abuf;
+ *aptr = 0;
+}
+
+uchar *
+lformat(int c, uchar *p)
+{
+ int trans =
+ c=='\b'? 'b':
+ c=='\t'? 't':
+ c=='\n'? 'n':
+ c=='\v'? 'v':
+ c=='\f'? 'f':
+ c=='\r'? 'r':
+ c=='\\'? '\\':
+ 0;
+ if(trans) {
+ *p++ = '\\';
+ *p++ = trans;
+ } else if(c<040 || c>=0177) {
+ *p++ = '\\';
+ *p++ = ((c>>6)&07) + '0';
+ *p++ = ((c>>3)&07) + '0';
+ *p++ = (c&07) + '0';
+ } else
+ *p++ = c;
+ return p;
+}
+