[master] 6dcbc76fd vte: Measure fields incrementally

Dridi Boukelmoune dridi.boukelmoune at gmail.com
Mon Aug 21 20:52:06 UTC 2023


commit 6dcbc76fd2e6a3346590cc666bb4a2fbbbb128ba
Author: Dridi Boukelmoune <dridi.boukelmoune at gmail.com>
Date:   Thu Aug 17 10:17:09 2023 +0200

    vte: Measure fields incrementally

diff --git a/include/vte.h b/include/vte.h
index e15d4c233..b570a5c84 100644
--- a/include/vte.h
+++ b/include/vte.h
@@ -30,4 +30,5 @@
 struct vte;
 
 struct vte *VTE_new(int maxfields, int width);
+int VTE_cat(struct vte *, const char *);
 void VTE_destroy(struct vte **);
diff --git a/lib/libvarnish/vte.c b/lib/libvarnish/vte.c
index 1d915a42d..554bb92c1 100644
--- a/lib/libvarnish/vte.c
+++ b/lib/libvarnish/vte.c
@@ -31,6 +31,7 @@
 
 #include "config.h"
 
+#include <errno.h>
 #include <stdlib.h>
 #include <string.h>
 #include <sys/types.h> /* for MUSL (ssize_t) */
@@ -91,6 +92,76 @@ VTE_destroy(struct vte **vtep)
 	FREE_OBJ(vte);
 }
 
+static int
+vte_update(struct vte *vte)
+{
+	const char *p, *q;
+	int len, fno;
+
+	AZ(vte->o_sep);
+
+	len = VSB_len(vte->vsb);
+	assert(len >= vte->c_off);
+
+	p = vte->vsb->s_buf + vte->c_off;
+	q = vte->vsb->s_buf + len;
+	for (; p < q; p++) {
+		if (vte->f_off < 0) {
+			while (p < q && *p != '\n')
+				p++;
+		}
+		if (vte->l_sz == 0 && *p == ' ') {
+			vte->f_off = -1;
+			continue;
+		}
+		if (*p == '\t' || *p == '\n') {
+			fno = vte->f_off;
+			if (fno >= 0 && vte->f_sz > vte->f_maxsz[fno])
+				vte->f_maxsz[fno] = vte->f_sz;
+			fno++;
+			assert(fno <= vte->f_maxcnt);
+			if (*p == '\t' && fno == vte->f_maxcnt) {
+				errno = EOVERFLOW;
+				vte->o_sep = -1;
+				return (-1);
+			}
+			vte->f_off = fno;
+			vte->f_sz = 0;
+		}
+		if (*p == '\n') {
+			vte->f_cnt = vmax(vte->f_cnt, vte->f_off);
+			vte->l_maxsz = vmax(vte->l_maxsz, vte->l_sz);
+			vte->f_off = 0;
+			vte->f_sz = 0;
+			vte->l_sz = 0;
+		} else {
+			vte->f_sz++;
+			vte->l_sz++;
+		}
+	}
+
+	vte->c_off = len;
+	return (0);
+}
+
+int
+VTE_cat(struct vte *vte, const char *s)
+{
+
+	CHECK_OBJ_NOTNULL(vte, VTE_MAGIC);
+	AN(s);
+
+	if (vte->o_sep != 0)
+		return (-1);
+
+	if (VSB_cat(vte->vsb, s) < 0) {
+		vte->o_sep = -1;
+		return (-1);
+	}
+
+	return (vte_update(vte));
+}
+
 void
 VCLI_VTE(struct cli *cli, struct vsb **src, int width)
 {


More information about the varnish-commit mailing list