Skip to content

Commit

Permalink
vmodtool: Add option to specify c names of arguments and avoid "bool"
Browse files Browse the repository at this point in the history
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

We use this facility to rename the "bool" argument to vmod_std functions to
"boola".

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.
  • Loading branch information
nigoroll committed Dec 4, 2024
1 parent c57f440 commit 7265024
Show file tree
Hide file tree
Showing 7 changed files with 38 additions and 25 deletions.
15 changes: 9 additions & 6 deletions bin/varnishtest/tests/m00003.vtc
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand All @@ -82,7 +85,7 @@ filewrite -a ${tmpdir}/libvmod_wrong.so {
[
[
"$VMOD",
"1.0",
"2.0",
"wrong",
"Vmod_vmod_wrong_Func",
"0000000000000000000000000000000000000000000000000000000000000000",
Expand All @@ -103,7 +106,7 @@ filewrite -a ${tmpdir}/libvmod_wrong.so {
[
[
"$VMOD",
"1.0",
"2.0",
"wrong",
"Vmod_vmod_wrong_Func",
"0000000000000000000000000000000000000000000000000000000000000000",
Expand All @@ -123,7 +126,7 @@ filewrite -a ${tmpdir}/libvmod_wrong.so {
[
[
"$VMOD",
"1.0",
"2.0",
"wrong",
"Vmod_vmod_wrong_Func",
"0000000000000000000000000000000000000000000000000000000000000000",
Expand All @@ -141,7 +144,7 @@ filewrite -a ${tmpdir}/libvmod_wrong.so {
[
[
"$VMOD",
"1.0",
"2.0",
"wrong",
"Vmod_vmod_wrong_Func",
"0000000000000000000000000000000000000000000000000000000000000000",
Expand All @@ -163,7 +166,7 @@ filewrite -a ${tmpdir}/libvmod_wrong.so {
[
[
"$VMOD",
"1.0",
"2.0",
"std",
"Vmod_vmod_std_Func",
"0000000000000000000000000000000000000000000000000000000000000000",
Expand Down
2 changes: 1 addition & 1 deletion bin/varnishtest/tests/m00055.vtc
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ filewrite -a ${tmpdir}/libvmod_wrong.so {
[
[
"$VMOD",
"1.0",
"2.0",
"wrong",
"Vmod_vmod_wrong_Func",
"0000000000000000000000000000000000000000000000000000000000000000",
Expand Down
13 changes: 8 additions & 5 deletions lib/libvcc/vcc_expr.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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);
Expand Down Expand Up @@ -642,18 +645,18 @@ 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)
fa->result = vcc_do_enum(tl, cfunc, strlen(fa->val), fa->val);
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);
Expand Down
3 changes: 2 additions & 1 deletion lib/libvcc/vcc_vmod.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
14 changes: 10 additions & 4 deletions lib/libvcc/vmodtool.py
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down Expand Up @@ -319,7 +323,7 @@ def __init__(self, wl, argnames, enums, end):
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:
Expand Down Expand Up @@ -385,6 +389,8 @@ def __init__(self, st, retval=True, prefix=""):
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)
Expand Down Expand Up @@ -466,8 +472,8 @@ def argstructure(self):
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:
Expand Down Expand Up @@ -1146,7 +1152,7 @@ def cstruct_init(self, fo):

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())
Expand Down
4 changes: 2 additions & 2 deletions vmod/vmod_std.vcc
Original file line number Diff line number Diff line change
Expand Up @@ -308,7 +308,7 @@ Example::
std.cache_req_body(std.bytes(real=10.0*1024));

$Function INT integer([STRING s], [INT fallback],
[BOOL bool], [BYTES bytes], [DURATION duration], [REAL real],
[BOOL bool:boola], [BYTES bytes], [DURATION duration], [REAL real],
[TIME time])

Returns an INT from a STRING, BOOL or other quantity.
Expand Down Expand Up @@ -376,7 +376,7 @@ Example::
}

$Function REAL real([STRING s], [REAL fallback], [INT integer],
[BOOL bool], [BYTES bytes], [DURATION duration],
[BOOL bool:boola], [BYTES bytes], [DURATION duration],
[TIME time])

Returns a REAL from a STRING, BOOL or other quantity.
Expand Down
12 changes: 6 additions & 6 deletions vmod/vmod_std_conversions.c
Original file line number Diff line number Diff line change
Expand Up @@ -149,15 +149,15 @@ vmod_integer(VRT_CTX, struct VARGS(integer) *a)

CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);

nargs = a->valid_s + a->valid_bool + a->valid_bytes +
nargs = a->valid_s + a->valid_boola + a->valid_bytes +
a->valid_duration + a->valid_real + a->valid_time;

if (!onearg(ctx, "integer", nargs))
return (0);

r = NAN;
if (a->valid_bool)
return (a->bool ? 1 : 0);
if (a->valid_boola)
return (a->boola ? 1 : 0);

if (a->valid_bytes)
return (a->bytes);
Expand Down Expand Up @@ -245,7 +245,7 @@ vmod_real(VRT_CTX, struct VARGS(real) *a)

CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);

nargs = a->valid_s + a->valid_integer + a->valid_bool + a->valid_bytes +
nargs = a->valid_s + a->valid_integer + a->valid_boola + a->valid_bytes +
a->valid_duration + a->valid_time;

if (!onearg(ctx, "real", nargs))
Expand All @@ -254,8 +254,8 @@ vmod_real(VRT_CTX, struct VARGS(real) *a)
if (a->valid_integer)
return ((VCL_REAL)a->integer);

if (a->valid_bool)
return ((VCL_REAL)(a->bool ? 1 : 0));
if (a->valid_boola)
return ((VCL_REAL)(a->boola ? 1 : 0));

if (a->valid_bytes)
return ((VCL_REAL)a->bytes);
Expand Down

0 comments on commit 7265024

Please sign in to comment.