[master] 45239c241 Use a turboencabulator to autocolumnate non-json vcl.list output

Poul-Henning Kamp phk at FreeBSD.org
Tue Feb 19 22:24:08 UTC 2019


commit 45239c2413098201a9c32e9fad597e352d694205
Author: Poul-Henning Kamp <phk at FreeBSD.org>
Date:   Tue Feb 19 22:23:14 2019 +0000

    Use a turboencabulator to autocolumnate non-json vcl.list output

diff --git a/bin/varnishd/cache/cache_vcl.c b/bin/varnishd/cache/cache_vcl.c
index cf9133ed6..88844c295 100644
--- a/bin/varnishd/cache/cache_vcl.c
+++ b/bin/varnishd/cache/cache_vcl.c
@@ -657,12 +657,15 @@ vcl_cli_list(struct cli *cli, const char * const *av, void *priv)
 {
 	struct vcl *vcl;
 	const char *flg;
+	struct vsb *vsb;
 
 	/* NB: Shall generate same output as mcf_vcl_list() */
 
 	(void)av;
 	(void)priv;
 	ASSERT_CLI();
+	vsb = VSB_new_auto();
+	AN(vsb);
 	VTAILQ_FOREACH(vcl, &vcl_head, list) {
 		if (vcl == vcl_active) {
 			flg = "active";
@@ -670,19 +673,20 @@ vcl_cli_list(struct cli *cli, const char * const *av, void *priv)
 			flg = "discarded";
 		} else
 			flg = "available";
-		VCLI_Out(cli, "%-10s %5s/%-8s %6u %s",
+		VSB_printf(vsb, "%s\t%s\t%s\t%6u\t%s",
 		    flg, vcl->state, vcl->temp, vcl->busy, vcl->loaded_name);
 		if (vcl->label != NULL) {
-			VCLI_Out(cli, " -> %s", vcl->label->loaded_name);
+			VSB_printf(vsb, "\t->\t%s", vcl->label->loaded_name);
 			if (vcl->nrefs)
-				VCLI_Out(cli, " (%d return(vcl)%s)",
+				VSB_printf(vsb, " (%d return(vcl)%s)",
 				    vcl->nrefs, vcl->nrefs > 1 ? "'s" : "");
 		} else if (vcl->nlabels > 0) {
-			VCLI_Out(cli, " (%d label%s)",
+			VSB_printf(vsb, "\t<-\t(%d label%s)",
 			    vcl->nlabels, vcl->nlabels > 1 ? "s" : "");
 		}
-		VCLI_Out(cli, "\n");
+		VSB_printf(vsb, "\n");
 	}
+	VCLI_VTE(cli, &vsb, 80);
 }
 
 static void v_matchproto_(cli_func_t)
diff --git a/bin/varnishd/mgt/mgt_vcl.c b/bin/varnishd/mgt/mgt_vcl.c
index 1a51ba07c..d9773c78f 100644
--- a/bin/varnishd/mgt/mgt_vcl.c
+++ b/bin/varnishd/mgt/mgt_vcl.c
@@ -799,11 +799,13 @@ mcf_vcl_list(struct cli *cli, const char * const *av, void *priv)
 	char *p;
 	struct vclprog *vp;
 	struct vcldep *vd;
+	struct vsb *vsb;
 
 	/* NB: Shall generate same output as vcl_cli_list() */
 
 	(void)av;
 	(void)priv;
+
 	if (MCH_Running()) {
 		if (!mgt_cli_askchild(&status, &p, "vcl.list\n")) {
 			VCLI_SetResult(cli, status);
@@ -811,26 +813,29 @@ mcf_vcl_list(struct cli *cli, const char * const *av, void *priv)
 		}
 		free(p);
 	} else {
+		vsb = VSB_new_auto();
+		AN(vsb);
+
 		VTAILQ_FOREACH(vp, &vclhead, list) {
-			VCLI_Out(cli, "%-10s %5s",
-			    vp == active_vcl ? "active" : "available",
-			    vp->state);
-			VCLI_Out(cli, "/%-8s", vp->warm ?
+			VSB_printf(vsb, "%s",
+			    vp == active_vcl ? "active" : "available");
+			VSB_printf(vsb, "\t%s\t%s", vp->state, vp->warm ?
 			    VCL_STATE_WARM : VCL_STATE_COLD);
-			VCLI_Out(cli, " %6s %s", "-", vp->name);
+			VSB_printf(vsb, "\t%6s\t%s", "-", vp->name);
 			if (mcf_is_label(vp)) {
 				vd = VTAILQ_FIRST(&vp->dfrom);
 				AN(vd);
-				VCLI_Out(cli, " -> %s", vd->to->name);
+				VSB_printf(vsb, "\t->\t%s", vd->to->name);
 				if (vp->nto > 0)
-					VCLI_Out(cli, " (%d return(vcl)%s)",
+					VSB_printf(vsb, " (%d return(vcl)%s)",
 					    vp->nto, vp->nto > 1 ? "'s" : "");
 			} else if (vp->nto > 0) {
-				VCLI_Out(cli, " (%d label%s)",
+				VSB_printf(vsb, "\t<-\t(%d label%s)",
 				    vp->nto, vp->nto > 1 ? "s" : "");
 			}
-			VCLI_Out(cli, "\n");
+			VSB_printf(vsb, "\n");
 		}
+		VCLI_VTE(cli, &vsb, 80);
 	}
 }
 
diff --git a/bin/varnishtest/tests/s00005.vtc b/bin/varnishtest/tests/s00005.vtc
index 4dac2f167..01c2def7e 100644
--- a/bin/varnishtest/tests/s00005.vtc
+++ b/bin/varnishtest/tests/s00005.vtc
@@ -105,7 +105,7 @@ varnish v1 -clijson "vcl.list -j"
 
 varnish v1 -start
 varnish v1 -cliok "vcl.list"
-varnish v1 -cliok "vcl.label snarf vcl1"
+varnish v1 -cliok "vcl.label slartibartfast vcl1"
 server s1 -start
 client c1 -run
 
diff --git a/bin/varnishtest/tests/u00000.vtc b/bin/varnishtest/tests/u00000.vtc
index ae91b169f..5eba11b19 100644
--- a/bin/varnishtest/tests/u00000.vtc
+++ b/bin/varnishtest/tests/u00000.vtc
@@ -101,7 +101,7 @@ shell -expect {VCL compiled.} {
 	varnishadm -n ${tmpdir}/v1 vcl.load vcl1 ${tmpdir}/vcl
 }
 
-shell -expect {active      auto/warm          - vcl1} {
+shell -expect {active   auto    warm         -    vcl1} {
 	varnishadm -n ${tmpdir}/v1 vcl.list
 }
 
@@ -145,8 +145,8 @@ shell {
 }
 
 varnish v2 -arg "-f ${tmpdir}/ok1" -arg "-f ${tmpdir}/ok2" -start
-varnish v2 -cliexpect {available *auto/warm *0 boot0} "vcl.list"
-varnish v2 -cliexpect {active *auto/warm *0 boot} "vcl.list"
+varnish v2 -cliexpect {available   auto    warm         0    boot0} "vcl.list"
+varnish v2 -cliexpect {active      auto    warm         0    boot} "vcl.list"
 varnish v2 -stop -wait
 
 # Test multiple -f options with a bad VCL
diff --git a/bin/varnishtest/tests/u00011.vtc b/bin/varnishtest/tests/u00011.vtc
index b53a9ba7b..25ddf8f1a 100644
--- a/bin/varnishtest/tests/u00011.vtc
+++ b/bin/varnishtest/tests/u00011.vtc
@@ -24,7 +24,7 @@ process p1 -expect-text 0 1 "PONG"
 
 process p1 -write "vcl.li\t\r"
 
-process p1 -expect-text 0 1 "active      auto/warm"
+process p1 -expect-text 0 1 "active   auto    warm         1    vcl1"
 
 process p1 -write "vcl.s\t\th\t vcl1\r"
 
diff --git a/bin/varnishtest/tests/u00012.vtc b/bin/varnishtest/tests/u00012.vtc
index e9822213a..2744ae40a 100644
--- a/bin/varnishtest/tests/u00012.vtc
+++ b/bin/varnishtest/tests/u00012.vtc
@@ -22,7 +22,7 @@ process p1 -expect-text 0 1 "PONG"
 
 process p1 -write "vcl.list\r"
 
-process p1 -expect-text 0 0 "auto/warm"
+process p1 -expect-text 0 0 "auto    warm"
 
 process p1 -write "vcl.show vcl1\r"
 
diff --git a/bin/varnishtest/tests/v00003.vtc b/bin/varnishtest/tests/v00003.vtc
index 6236f28f1..5ef44b95b 100644
--- a/bin/varnishtest/tests/v00003.vtc
+++ b/bin/varnishtest/tests/v00003.vtc
@@ -88,7 +88,7 @@ varnish v1 -expect !VBE.vcl1.default.happy
 varnish v1 -cliok "param.set max_esi_depth 42"
 varnish v1 -clierr 300 "vcl.state vcl1 warm"
 
-varnish v1 -cliexpect "available *cold/cold *[0-9]+ *vcl1\\s+active *warm/warm *[0-9]+ *vcl2" "vcl.list"
+varnish v1 -cliexpect "available *cold *cold *[0-9]+ *vcl1\\s+active *warm *warm *[0-9]+ *vcl2" "vcl.list"
 
 # A warm-up failure can also fail a child start
 varnish v1 -cliok stop
diff --git a/bin/varnishtest/tests/v00045.vtc b/bin/varnishtest/tests/v00045.vtc
index 0f9cdf5a6..2591f9d36 100644
--- a/bin/varnishtest/tests/v00045.vtc
+++ b/bin/varnishtest/tests/v00045.vtc
@@ -17,7 +17,7 @@ varnish v1 -cliok "vcl.state vcl1 cold"
 # We should now see it as cooling
 delay 1
 
-varnish v1 -cliexpect "cold/cooling.*vcl1" vcl.list
+varnish v1 -cliexpect "available   cold    cooling         0    vcl1" vcl.list
 varnish v1 -clijson "vcl.list -j"
 
 # It can't be warmed up yet
@@ -26,7 +26,7 @@ varnish v1 -cliexpect "vmod-debug ref on vcl1" "vcl.state vcl1 warm"
 
 # It will eventually cool down
 delay 2
-varnish v1 -cliexpect "cold/cold.*vcl1" vcl.list
+varnish v1 -cliexpect "available   cold    cold         0    vcl1" vcl.list
 varnish v1 -clijson "vcl.list -j"
 
 # At this point it becomes possible to warm up again
diff --git a/doc/sphinx/reference/vtla.rst b/doc/sphinx/reference/vtla.rst
index 905d2d6c1..ba80b8958 100644
--- a/doc/sphinx/reference/vtla.rst
+++ b/doc/sphinx/reference/vtla.rst
@@ -90,6 +90,9 @@ VSS
 VTC
     Varnish Test Code -- a test-specification for the varnishtest program. 
 
+VTE
+    Varnish Turbo Encabulator
+
 VTLA
     Varnish Three Letter Acronym -- No rule without an exception. 
 
diff --git a/include/vcli_serve.h b/include/vcli_serve.h
index 00b364ff4..71beae3a1 100644
--- a/include/vcli_serve.h
+++ b/include/vcli_serve.h
@@ -106,3 +106,6 @@ cli_func_t	VCLS_func_help;
 cli_func_t	VCLS_func_help_json;
 cli_func_t	VCLS_func_ping;
 cli_func_t	VCLS_func_ping_json;
+
+/* From libvarnish/vte.c */
+void VCLI_VTE(struct cli *cli, struct vsb **src, int width);
diff --git a/lib/libvarnish/Makefile.am b/lib/libvarnish/Makefile.am
index a7a57dd49..bb27d4e1e 100644
--- a/lib/libvarnish/Makefile.am
+++ b/lib/libvarnish/Makefile.am
@@ -39,6 +39,7 @@ libvarnish_a_SOURCES = \
 	vss.c \
 	vsub.c \
 	vtcp.c \
+	vte.c \
 	vtim.c \
 	vus.c
 
diff --git a/lib/libvarnish/vte.c b/lib/libvarnish/vte.c
new file mode 100644
index 000000000..3063d4b90
--- /dev/null
+++ b/lib/libvarnish/vte.c
@@ -0,0 +1,116 @@
+/*-
+ * Copyright (c) 2019 Varnish Software AS
+ * All rights reserved.
+ *
+ * Author: Poul-Henning Kamp <phk at phk.freebsd.dk>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+#include "config.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "vdef.h"
+#include "vqueue.h"
+
+#include "vas.h"
+#include "vcli_serve.h"
+#include "vsb.h"
+
+#define MAXCOL 10
+
+void
+VCLI_VTE(struct cli *cli, struct vsb **src, int width)
+{
+	int w_col[MAXCOL];
+	int n_col = 0;
+	int w_ln = 0;
+	int cc = 0;
+	int wc = 0;
+	int wl = 0;
+	int nsp;
+	const char *p;
+	char *s;
+
+	AN(cli);
+	AN(src);
+	AN(*src);
+	AZ(VSB_finish(*src));
+	if (VSB_len(*src) == 0) {
+		VSB_destroy(src);
+		return;
+	}
+	s = VSB_data(*src);
+	AN(s);
+	memset(w_col, 0, sizeof w_col);
+	for (p = s; *p ; p++) {
+		if (*p == '\t' || *p == '\n') {
+			if (wc > w_col[cc])
+				w_col[cc] = wc;
+			cc++;
+			assert(cc < MAXCOL);
+			wc = 0;
+		}
+		if (*p == '\n') {
+			if (cc > n_col)
+				n_col = cc;
+			cc = 0;
+			wc = 0;
+			if (wl > w_ln)
+				w_ln = wl;
+			wl = 0;
+		}
+		wc++;
+		wl++;
+	}
+
+	if (n_col == 0)
+		return;
+	AN(n_col);
+
+	nsp = (width - (w_ln)) / n_col;
+	if (nsp > 3)
+		nsp = 3;
+
+	cc = 0;
+	wc = 0;
+	for (p = s; *p ; p++) {
+		if (*p == '\t') {
+			while (wc++ < w_col[cc] + nsp)
+				VCLI_Out(cli, " ");
+			cc++;
+			wc = 0;
+		} else if (*p == '\n') {
+			VCLI_Out(cli, "%c", *p);
+			cc = 0;
+			wc = 0;
+		} else {
+			VCLI_Out(cli, "%c", *p);
+			wc++;
+		}
+	}
+	VSB_destroy(src);
+}
+


More information about the varnish-commit mailing list