shithub: libacme

Download patch

ref: 2a9f9c14cc2ef1fad0af586db556a0fcc803a4a4
parent: 2e2bacc37ba01af14d632a7f698c1899f631ad5c
author: james palmer <james@biobuf.link>
date: Sun Jun 13 21:47:52 EDT 2021

fix event parsing :)

--- a/acme.h
+++ b/acme.h
@@ -15,6 +15,10 @@
 	int datafd;
 	int eventfd;
 	int bodyfd;
+
+	char buf[512];
+	char *bufp;
+	int nbuf;
 	
 	void *aux;
 	
--- a/event.c
+++ b/event.c
@@ -6,22 +6,28 @@
 #include "acme.h"
 
 static int
-getc(int fd)
+getc(AWin *w)
 {
-	char buf[1];
-	
-	if(read(fd, buf, sizeof(buf)) > 0)
-		return buf[0];
-	return -1;
+	if(w->nbuf == 0){
+		w->nbuf = read(w->eventfd, w->buf, sizeof(w->buf));
+		if(w->nbuf <= 0) {
+			werrstr("event read failed: %r");
+			return -1;
+		}
+		w->bufp = w->buf;
+	}
+
+	w->nbuf--;
+	return *w->bufp++;
 }
 
 static int
-getnum(int fd)
+getnum(AWin *w)
 {
 	int c, n;
 
 	n = 0;
-	while('0' <= (c = getc(fd)) && c <= '9')
+	while('0' <= (c = getc(w)) && c <= '9')
 		n = n*10+(c-'0');
 	
 	if(c != ' '){
@@ -33,42 +39,36 @@
 }
 
 static long
-getrune(int fd)
+getrune(AWin *w)
 {
-	int c, i;
-	Rune rune;
+	Rune r;
 	char buf[UTFmax];
-	
-	c = getc(fd);
-	if(c < Runeself)
-		return c;
-	buf[0] = c;
-	
-	for(i = 1; i < UTFmax;) {
-		c = getc(fd);
-		if(c < 0)
-			return c;
-		buf[i++] = c;
-		
-		if(fullrune(buf, i)) {
-			chartorune(&rune, buf);
-			return rune;
-		}
+	int n;
+
+	n = 0;
+	r = getc(w);
+	buf[n++] = r;
+
+	if(r >= Runeself) {
+		while(!fullrune(buf, n))
+			buf[n++] = getc(w);
+		chartorune(&r, buf);
 	}
-	
-	return -1;
+
+	return r;
 }
 
 static int
-getdata(int fd, AEvent *e)
+getdata(AWin *w, AEvent *e)
 {
 	int i, n, o;
 	Rune r;
 	
 	o = 0;
-	n = getnum(fd);
+	n = getnum(w);
+
 	for(i = 0; i < n; i++) {
-		if((r = getrune(fd)) == -1)
+		if((r = getrune(w)) == -1)
 			break;
 		o += runetochar(e->text + o, &r);
 	}
@@ -84,13 +84,13 @@
 	
 	flags = 0;
 loop:
-	e->origin = getc(w->eventfd);
-	e->type = getc(w->eventfd);
-	e->q0 = getnum(w->eventfd);
-	e->q1 = getnum(w->eventfd);
-	e->flags = getnum(w->eventfd);
-	e->ntext = getdata(w->eventfd, e);
-	if(getc(w->eventfd) != '\n') {
+	e->origin = getc(w);
+	e->type = getc(w);
+	e->q0 = getnum(w);
+	e->q1 = getnum(w);
+	e->flags = getnum(w);
+	e->ntext = getdata(w, e);
+	if(getc(w) != '\n') {
 		werrstr("unterminated message");
 		return -1;
 	}