shithub: pplay

Download patch

ref: 4f75866d56184b1a5ccc0c7b3a7713f3a5c610e6
parent: 57fb3f340445e45af9e1e59323b1ee2e2fd30f1e
author: qwx <qwx@sciops.net>
date: Sun Nov 20 12:17:25 EST 2022

prepare for piping: link chains, not nodes; properly separate insert/replace; generalize pipeto

--- a/cmd.c
+++ b/cmd.c
@@ -15,13 +15,13 @@
 static int epfd[2];
 
 static void
-printchunks(void)
+printchunks(Chunk *r)
 {
 	Chunk *c;
 
 	fprint(2, "chunklist dot %zux %zux %zux: ", 
 		dot.from.pos, dot.pos, dot.to.pos);
-	for(c=norris.right; c!=&norris; c=c->right)
+	for(c=r->right; c!=r; c=c->right)
 		fprint(2, "%#p:%zux ", c, c->bufsz);
 	fprint(2, "\n");
 }
@@ -35,6 +35,8 @@
 	c = emalloc(sizeof *c);
 	c->bufsz = n;
 	c->buf = emalloc(c->bufsz);
+	c->left = c;
+	c->right = c;
 	return c;
 }
 
@@ -61,9 +63,9 @@
 static void
 linkchunk(Chunk *left, Chunk *c)
 {
-	c->right = left->right;
+	c->left->right = left->right;
 	c->left = left;
-	c->right->left = c;
+	left->right->left = c->left;
 	left->right = c;
 }
 
@@ -282,29 +284,35 @@
 }
 
 static int
-paste(char *)
+replace(char *)
 {
 	Chunk *c, *l, *dotc;
 
 	c = clonechunk();
-	if(dot.from.pos == 0 && dot.to.pos == totalsz){		/* insert */
-		linkchunk(p2c(dot.pos, nil), c);
-		setrange(dot.pos, dot.pos + c->bufsz);
-		totalsz += c->bufsz;
-	}else{						/* replace */
-		dotc = p2c(dot.pos, nil);
-		l = dotc->left;
-		totalsz -= dotc->bufsz;
-		unlinkchunk(dotc);
-		freechunk(dotc);
-		linkchunk(l, c);
-		setrange(dot.from.pos, dot.from.pos + c->bufsz);
-		totalsz += c->bufsz;
-	}
+	dotc = p2c(dot.pos, nil);
+	l = dotc->left;
+	totalsz -= dotc->bufsz;
+	unlinkchunk(dotc);
+	freechunk(dotc);
+	linkchunk(l, c);
+	setrange(dot.from.pos, dot.from.pos + c->bufsz);
+	totalsz += c->bufsz;
 	return 1;
 }
 
 static int
+insert(char *)
+{
+	Chunk *c;
+
+	c = clonechunk();
+	linkchunk(p2c(dot.pos, nil), c);
+	setrange(dot.pos, dot.pos + c->bufsz);
+	totalsz += c->bufsz;
+	return 1;
+}
+
+static int
 copy(char *)
 {
 	splitdot();
@@ -330,7 +338,6 @@
 	Chunk *c, *d;
 
 	Δ = 0;
-	printchunks();
 	for(c=norris.right; c!=&norris; c=d){
 		if(Δ + c->bufsz >= dot.from.pos)
 			break;
@@ -384,11 +391,10 @@
 {
 	int n;
 	usize off;
-	Chunk *c, *nc;
+	Chunk *rc, *c, *nc;
 
-	c = newchunk(Iochunksz);
-	linkchunk(&norris, c);
-	for(off=0;; off+=n){
+	rc = newchunk(Iochunksz);
+	for(off=0, c=rc;; off+=n){
 		if(off == Iochunksz){
 			totalsz += Iochunksz;
 			nc = newchunk(Iochunksz);
@@ -405,7 +411,8 @@
 	c->buf = erealloc(c->buf, off, c->bufsz);
 	c->bufsz = off;
 	totalsz += c->bufsz;
-	return norris.right;
+	printchunks(rc);
+	return rc;
 }
 
 static int
@@ -435,26 +442,47 @@
 static void
 rc(void *s)
 {
-	close(epfd[1]);
 	dup(epfd[0], 0);
+	dup(epfd[1], 1);
 	close(epfd[0]);
+	close(epfd[1]);
 	procexecl(nil, "/bin/rc", "rc", "-c", s, nil);
 	sysfatal("procexec: %r");
 }
 
 static int
-pipeto(char *arg)
+pipeline(char *arg, int rr, int wr)
 {
 	if(pipe(epfd) < 0)
 		sysfatal("pipe: %r");
 	if(procrfork(rc, arg, mainstacksize, RFFDG|RFNOTEG|RFNAMEG) < 0)
 		sysfatal("procrfork: %r");
-	close(epfd[0]);
-	writebuf(epfd[1]);
+	if(wr)
+		writebuf(epfd[1]);
 	close(epfd[1]);
+	USED(rr);
+	close(epfd[0]);
 	return 0;
 }
 
+static int
+pipeto(char *arg)
+{
+	return pipeline(arg, 0, 1);
+}
+
+static int
+pipefrom(char *arg)
+{
+	return pipeline(arg, 1, 0);
+}
+
+static int
+pipethrough(char *arg)
+{
+	return pipeline(arg, 1, 1);
+}
+
 /* the entire string is treated as the filename, ie.
  * spaces and any other weird characters will be part
  * of it */
@@ -502,7 +530,7 @@
 	case 'c': return copy(s);
 	case 'd': return cut(s);
 	case 'm': return forcemerge(s);
-	case 'p': return paste(s);
+	case 'p': return dot.from.pos == 0 && dot.to.pos == totalsz ? insert(s) : replace(s);
 //	case 'r': return readfrom(s);
 	case 'w': return writeto(s);
 	case 'x': return crop(s);
@@ -514,8 +542,12 @@
 int
 loadin(int fd)
 {
-	if(readintochunks(fd) == nil)
+	Chunk *c;
+
+	if((c = readintochunks(fd)) == nil)
 		sysfatal("loadin: %r");
+	linkchunk(&norris, c);
+	printchunks(&norris);
 	setrange(0, totalsz);
 	return 0;
 }