[master] 99efe0ec8 vmodtool: Add option to specify c names of arguments and avoid "bool"
Nils Goroll
nils.goroll at uplex.de
Thu Apr 17 13:37:05 UTC 2025
commit 99efe0ec8a2630eef04533869e63adef6b416b0d
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 22bd4ba71..0ace9b61d 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 7c4c70342..e41f61dde 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 781929383..20cb31b46 100644
--- a/doc/sphinx/reference/vmod.rst
+++ b/doc/sphinx/reference/vmod.rst
@@ -196,6 +196,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
@@ -550,13 +553,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 1e3a6e054..280476245 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 a2e8969ee..e4be1760c 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:
@@ -1163,7 +1169,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