[7.6] 69259780b vmodtool: Add option to specify c names of arguments and avoid "bool"
Walid Boudebouda
walid.boudebouda at gmail.com
Mon May 12 15:29:05 UTC 2025
commit 69259780b790fe287c6dad79d412dd1ab1526ec2
Author: Nils Goroll <nils.goroll at uplex.de>
Date: Tue Dec 3 18:32:29 2024 +0100
vmodtool: Add option to specify c names of arguments and avoid "bool"
I tried gcc version 15.0.0 20241203 and even without -std=c23, it would reserve
"bool":
In file included from vcc_std_if.c:10:
vcc_std_if.h:78:33: error: two or more data types in declaration specifiers
78 | VCL_BOOL bool;
| ^~~~
(and more)
So this patch adds the option to specify the c name of arguments to vmod
functions/methods by separating it with a colon in the spec in the VCC file.
vclname:cname
In the next commit, we use this facility to rename the "bool" argument to
vmod_std functions to "boolean".
Implementation
--------------
The cname needs to be specified by the VMOD author because it is also used in
the vmod implementation.
Obviously, VCC needs to know that name, too, to generate argument structs, so we
need to transport it from the VMOD to VCC via the JSON spec. A logical place for
cname is next to the name, because the other attributes following in the
argument spec array are optional. So this changes the JSON spec format, and,
consequently, we need to increase the version number.
So, ultimately, this is a breaking change with respect to vmodtool: One can not
import vmods built before this change. We could add compatibility for this case,
but as we have a tradition of forcing rebuilds with each release by bumping the
VRT major number anyway, I did not see my time well spent on implementing
backwards compatibility.
Groundwork for the fix of #4294
diff --git a/bin/varnishtest/tests/m00003.vtc b/bin/varnishtest/tests/m00003.vtc
index 635b3f0aa..eafd30197 100644
--- a/bin/varnishtest/tests/m00003.vtc
+++ b/bin/varnishtest/tests/m00003.vtc
@@ -59,12 +59,15 @@ varnish v1 -errvcl {Not string[2]} { import wrong; }
filewrite ${tmpdir}/libvmod_wrong.so "VMOD_JSON_SPEC\x02" "[[\"$VBLA\"]]" "\x03"
varnish v1 -errvcl {Not $VMOD[3]} { import wrong; }
+filewrite ${tmpdir}/libvmod_wrong.so "VMOD_JSON_SPEC\x02" "[[\"$VMOD\",\"1.0\"]]" "\x03"
+varnish v1 -errvcl {Syntax != 2.0} { import wrong; }
+
filewrite ${tmpdir}/libvmod_wrong.so "VMOD_JSON_SPEC\x02"
filewrite -a ${tmpdir}/libvmod_wrong.so {
[
[
"$VMOD",
- "1.0",
+ "2.0",
"wrong",
"Vmod_vmod_wrong_Func",
"0000000000000000000000000000000000000000000000000000000000000000",
@@ -82,7 +85,7 @@ filewrite -a ${tmpdir}/libvmod_wrong.so {
[
[
"$VMOD",
- "1.0",
+ "2.0",
"wrong",
"Vmod_vmod_wrong_Func",
"0000000000000000000000000000000000000000000000000000000000000000",
@@ -103,7 +106,7 @@ filewrite -a ${tmpdir}/libvmod_wrong.so {
[
[
"$VMOD",
- "1.0",
+ "2.0",
"wrong",
"Vmod_vmod_wrong_Func",
"0000000000000000000000000000000000000000000000000000000000000000",
@@ -123,7 +126,7 @@ filewrite -a ${tmpdir}/libvmod_wrong.so {
[
[
"$VMOD",
- "1.0",
+ "2.0",
"wrong",
"Vmod_vmod_wrong_Func",
"0000000000000000000000000000000000000000000000000000000000000000",
@@ -141,7 +144,7 @@ filewrite -a ${tmpdir}/libvmod_wrong.so {
[
[
"$VMOD",
- "1.0",
+ "2.0",
"wrong",
"Vmod_vmod_wrong_Func",
"0000000000000000000000000000000000000000000000000000000000000000",
@@ -163,7 +166,7 @@ filewrite -a ${tmpdir}/libvmod_wrong.so {
[
[
"$VMOD",
- "1.0",
+ "2.0",
"std",
"Vmod_vmod_std_Func",
"0000000000000000000000000000000000000000000000000000000000000000",
diff --git a/bin/varnishtest/tests/m00055.vtc b/bin/varnishtest/tests/m00055.vtc
index 7d17010aa..183fed0a3 100644
--- a/bin/varnishtest/tests/m00055.vtc
+++ b/bin/varnishtest/tests/m00055.vtc
@@ -16,7 +16,7 @@ filewrite -a ${tmpdir}/libvmod_wrong.so {
[
[
"$VMOD",
- "1.0",
+ "2.0",
"wrong",
"Vmod_vmod_wrong_Func",
"0000000000000000000000000000000000000000000000000000000000000000",
diff --git a/doc/sphinx/reference/vmod.rst b/doc/sphinx/reference/vmod.rst
index 38868e002..5039830d0 100644
--- a/doc/sphinx/reference/vmod.rst
+++ b/doc/sphinx/reference/vmod.rst
@@ -190,6 +190,9 @@ declarations:
with `n` starting at 1 and incrementing with the argument's
position.
+Optionally, the VCL and C argument names can be specified independently using
+the ``<vclname>:<cname>`` syntax. See :ref:`ref-vmod-symbols` for details.
+
.. _ref-vmod-vcl-c-objects:
Objects and methods
@@ -544,13 +547,14 @@ For the above, the *<xxx>* placeholders are defined as:
The vmod name fro the ``$Module`` stanza of the ``.vcc`` file.
*<argument>*
- The function or method argument name
+ The function or method argument *cname* or, if not given, *vclname*
+ as specified using the *<vclname>:<cname>* syntax.
The other placeholders should be self-explanatory as the name of the respective
-function, class, method or handler name.
+function, class, method or handler.
-In summary, only some symbol names (those with *<prefix>*) can be influenced by
-the vmod author.
+In summary, symbol names can either be influenced by the vmod author globally
+using ``$Prefix``, or using the *<vclname>:<cname>* syntax for argument names.
.. _ref-vmod-private-pointers:
diff --git a/lib/libvcc/vcc_expr.c b/lib/libvcc/vcc_expr.c
index 15f03626f..c4fcf397c 100644
--- a/lib/libvcc/vcc_expr.c
+++ b/lib/libvcc/vcc_expr.c
@@ -558,7 +558,7 @@ vcc_func(struct vcc *tl, struct expr **e, const void *priv,
fa->result = vcc_priv_arg(tl, vvp->value, sym);
vvp = VTAILQ_NEXT(vvp, list);
if (vvp != NULL)
- fa->name = vvp->value;
+ fa->cname = fa->name = vvp->value;
continue;
}
fa->type = VCC_Type(vvp->value);
@@ -567,6 +567,9 @@ vcc_func(struct vcc *tl, struct expr **e, const void *priv,
if (vvp != NULL) {
fa->name = vvp->value;
vvp = VTAILQ_NEXT(vvp, list);
+ AN(vvp); /* vmod_syntax 2.0 */
+ fa->cname = vvp->value;
+ vvp = VTAILQ_NEXT(vvp, list);
if (vvp != NULL) {
fa->val = vvp->value;
vvp = VTAILQ_NEXT(vvp, list);
@@ -642,9 +645,9 @@ vcc_func(struct vcc *tl, struct expr **e, const void *priv,
VTAILQ_FOREACH_SAFE(fa, &head, list, fa2) {
n++;
if (fa->optional) {
- AN(fa->name);
+ AN(fa->cname);
bprintf(ssa, "\v1.valid_%s = %d,\n",
- fa->name, fa->avail);
+ fa->cname, fa->avail);
e1 = vcc_expr_edit(tl, e1->fmt, ssa, e1, NULL);
}
if (fa->result == NULL && fa->type == ENUM && fa->val != NULL)
@@ -652,8 +655,8 @@ vcc_func(struct vcc *tl, struct expr **e, const void *priv,
if (fa->result == NULL && fa->val != NULL)
fa->result = vcc_mk_expr(fa->type, "%s", fa->val);
if (fa->result != NULL && sa != NULL) {
- if (fa->name)
- bprintf(ssa, "\v1.%s = \v2,\n", fa->name);
+ if (fa->cname)
+ bprintf(ssa, "\v1.%s = \v2,\n", fa->cname);
else
bprintf(ssa, "\v1.arg%d = \v2,\n", n);
e1 = vcc_expr_edit(tl, e1->fmt, ssa, e1, fa->result);
diff --git a/lib/libvcc/vcc_vmod.c b/lib/libvcc/vcc_vmod.c
index 7e7b3b8af..6fe8b0450 100644
--- a/lib/libvcc/vcc_vmod.c
+++ b/lib/libvcc/vcc_vmod.c
@@ -162,7 +162,8 @@ vcc_ParseJSON(const struct vcc *tl, const char *jsn, struct vmod_import *vim)
AN(vv3);
assert(vjsn_is_string(vv3));
vim->vmod_syntax = strtod(vv3->value, NULL);
- assert (vim->vmod_syntax == 1.0);
+ if (vim->vmod_syntax != 2.0)
+ return ("Syntax != 2.0");
vv3 = VTAILQ_NEXT(vv3, list);
AN(vv3);
diff --git a/lib/libvcc/vmodtool.py b/lib/libvcc/vmodtool.py
index 2d3d94640..3235dd2c5 100755
--- a/lib/libvcc/vmodtool.py
+++ b/lib/libvcc/vmodtool.py
@@ -27,6 +27,10 @@
# 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.
+#
+# syntax version history:
+# 1.0: initial
+# 2.0: added cname (nm2) after argument name
"""
Read the first existing file from arguments or vmod.vcc and produce:
@@ -319,7 +323,7 @@ class arg(CType):
self.defval = x
def jsonproto(self, jl):
- jl.append([self.vt, self.nm, self.defval, self.spec])
+ jl.append([self.vt, self.nm, self.nm2, self.defval, self.spec])
if self.opt:
jl[-1].append(True)
while jl[-1][-1] is None:
@@ -385,6 +389,8 @@ class ProtoType():
err("arguments cannot be of type '%s'" % t.vt, warn=False)
if t.nm is None:
t.nm2 = "arg%d" % n
+ elif ':' in t.nm:
+ [t.nm, t.nm2] = t.nm.split(':')
else:
t.nm2 = t.nm
self.args.append(t)
@@ -466,8 +472,8 @@ class ProtoType():
s = "\n" + self.argstructname() + " {\n"
for i in self.args:
if i.opt:
- assert i.nm is not None
- s += "\tchar\t\t\tvalid_%s;\n" % i.nm
+ assert i.nm2 is not None
+ s += "\tchar\t\t\tvalid_%s;\n" % i.nm2
for i in self.args:
s += "\t" + i.ct
if len(i.ct) < 8:
@@ -1146,7 +1152,7 @@ class vcc():
def iter_json(self, fnx):
- jl = [["$VMOD", "1.0", self.modname, self.csn, self.file_id]]
+ jl = [["$VMOD", "2.0", self.modname, self.csn, self.file_id]]
jl.append(["$CPROTO"])
for i in open(fnx):
jl[-1].append(i.rstrip())
More information about the varnish-commit
mailing list