[master] 9f5044eb8 Macros for VCL_STRANDS creation

Nils Goroll nils.goroll at uplex.de
Mon Nov 1 15:50:09 UTC 2021


commit 9f5044eb8d551bafeecdefc1d91529abfe8b9490
Author: Nils Goroll <nils.goroll at uplex.de>
Date:   Tue Oct 26 17:39:28 2021 +0200

    Macros for VCL_STRANDS creation

diff --git a/bin/varnishd/cache/cache_vrt.c b/bin/varnishd/cache/cache_vrt.c
index 1991aea77..31424c2ca 100644
--- a/bin/varnishd/cache/cache_vrt.c
+++ b/bin/varnishd/cache/cache_vrt.c
@@ -54,6 +54,7 @@
 #include "common/vsmw.h"
 #include "proxy/cache_proxy.h"
 
+// NOT using TOSTRANDS() to create a NULL pointer element despite n == 0
 const struct strands *vrt_null_strands = &(struct strands){
 	.n = 0,
 	.p = (const char *[1]){NULL}
diff --git a/doc/changes.rst b/doc/changes.rst
index c290a644c..77eba21c0 100644
--- a/doc/changes.rst
+++ b/doc/changes.rst
@@ -31,6 +31,20 @@ http://varnish-cache.org/docs/trunk/whats-new/index.html and via
 individual releases. These documents are updated as part of the
 release process.
 
+===============================
+Varnish Cache NEXT (2022-03-15)
+===============================
+
+* Added macros ``TOSTRAND(s)`` and ``TOSTRANDS(x, ...)`` to create a
+  ``struct strands *`` (intended to be used as a ``VCL_STANDS``) from
+  a single string ``s`` or ``x`` strings, respectively.
+
+  Note that the macros create a local pointer value (on the stack),
+  which should only be used for local variables and parameters, but
+  never as a function return value (use ``VRT_AllocStrandsWS()`` for
+  that or just return a ``VCL_STRING`` result created with
+  ``VRT_StrandsWS()``).
+
 ================================
 Varnish Cache 7.0.0 (2021-09-15)
 ================================
diff --git a/include/vrt.h b/include/vrt.h
index 005e485bb..a0d4f10ff 100644
--- a/include/vrt.h
+++ b/include/vrt.h
@@ -281,6 +281,12 @@ struct strands {
  */
 extern const struct strands *vrt_null_strands;
 
+/*
+ * Macros for VCL_STRANDS creation
+ */
+#define TOSTRAND(s)(&(struct strands){.n=1,.p=(const char *[1]){s}})
+#define TOSTRANDS(x, ...)(&(struct strands){.n=x,.p=(const char *[x]){__VA_ARGS__}})
+
 /***********************************************************************
  * VCL_BLOB:
  *
diff --git a/lib/libvcc/vcc_expr.c b/lib/libvcc/vcc_expr.c
index 1c601931c..cdd2bd498 100644
--- a/lib/libvcc/vcc_expr.c
+++ b/lib/libvcc/vcc_expr.c
@@ -180,9 +180,8 @@ vcc_expr_edit(struct vcc *tl, vcc_type_t fmt, const char *p, struct expr *e1,
 				VSB_cat(e->vsb,
 				    "\nVRT_STRANDS_string(ctx,\v+\n");
 				VSB_printf(e->vsb,
-				    "&(struct strands){.n = %d, .p = "
-				    "(const char *[%d]){\n%s\n}}",
-				    e3->nstr, e3->nstr, VSB_data(e3->vsb));
+				    "TOSTRANDS(%d,%s)",
+				    e3->nstr, VSB_data(e3->vsb));
 				VSB_cat(e->vsb,
 				    "\v-\n)\n");
 			} else {
@@ -193,10 +192,8 @@ vcc_expr_edit(struct vcc *tl, vcc_type_t fmt, const char *p, struct expr *e1,
 		case 't':
 			e3 = (*p == 'T' ? e1 : e2);
 			AN(e3);
-			VSB_printf(e->vsb,
-			    "&(struct strands){.n = %d, .p = "
-			    "(const char *[%d]){\n%s\n}}",
-			    e3->nstr, e3->nstr, VSB_data(e3->vsb));
+			VSB_printf(e->vsb, "TOSTRANDS(%d,%s)",
+			    e3->nstr, VSB_data(e3->vsb));
 			break;
 		case '1':
 			VSB_cat(e->vsb, VSB_data(e1->vsb));
diff --git a/vmod/vmod_debug.c b/vmod/vmod_debug.c
index e467e4146..07f1039af 100644
--- a/vmod/vmod_debug.c
+++ b/vmod/vmod_debug.c
@@ -517,15 +517,9 @@ event_warm(VRT_CTX, const struct vmod_priv *priv)
 {
 	struct priv_vcl *priv_vcl;
 	char buf[32];
-	const char *p[2];
-	struct strands msg[1];
 
 	// Using VSLs for coverage
-	msg->n = 2;
-	msg->p = p;
-	p[0] = VCL_Name(ctx->vcl);
-	p[1] = ": VCL_EVENT_WARM";
-	VSLs(SLT_Debug, 0, msg);
+	VSLs(SLT_Debug, 0, TOSTRANDS(2, VCL_Name(ctx->vcl), ": VCL_EVENT_WARM"));
 
 	AN(ctx->msg);
 	if (cache_param->max_esi_depth == 42) {
diff --git a/vmod/vmod_directors_shard.c b/vmod/vmod_directors_shard.c
index 19f48339b..744e3552b 100644
--- a/vmod/vmod_directors_shard.c
+++ b/vmod/vmod_directors_shard.c
@@ -373,8 +373,6 @@ static inline uint32_t
 shard_get_key(VRT_CTX, const struct vmod_directors_shard_param *p)
 {
 	struct http *http;
-	struct strands s[1];
-	const char *sp[1];
 	VCL_ENUM by = default_by(p->by);
 
 	if (by == VENUM(KEY) || by == VENUM(BLOB))
@@ -390,10 +388,7 @@ shard_get_key(VRT_CTX, const struct vmod_directors_shard_param *p)
 			AN(ctx->http_bereq);
 			AN(http = ctx->http_bereq);
 		}
-		sp[0] = http->hd[HTTP_HDR_URL].b;
-		s->n = 1;
-		s->p = sp;
-		return (VRT_HashStrands32(s));
+		return (VRT_HashStrands32(TOSTRAND(http->hd[HTTP_HDR_URL].b)));
 	}
 	WRONG("by enum");
 }
diff --git a/vmod/vmod_directors_shard_cfg.c b/vmod/vmod_directors_shard_cfg.c
index 6cd709df8..d76c61c6b 100644
--- a/vmod/vmod_directors_shard_cfg.c
+++ b/vmod/vmod_directors_shard_cfg.c
@@ -270,8 +270,6 @@ shardcfg_hashcircle(struct sharddir *shardd)
 	const char *ident;
 	const int len = 12; // log10(UINT32_MAX) + 2;
 	char s[len];
-	struct strands ss[1];
-	const char *ssp[2];
 
 	CHECK_OBJ_NOTNULL(shardd, SHARDDIR_MAGIC);
 	AZ(shardd->hashcircle);
@@ -309,12 +307,9 @@ shardcfg_hashcircle(struct sharddir *shardd)
 
 		for (j = 0; j < r; j++) {
 			assert(snprintf(s, len, "%d", j) < len);
-			ss->n = 2;
-			ssp[0] = ident;
-			ssp[1] = s;
-			ss->p = ssp;
 			assert (i < n_points);
-			shardd->hashcircle[i].point = VRT_HashStrands32(ss);
+			shardd->hashcircle[i].point =
+			    VRT_HashStrands32(TOSTRANDS(2, ident, s));
 			shardd->hashcircle[i].host = h;
 			i++;
 		}


More information about the varnish-commit mailing list