Commit c796ea52 authored by Poul-Henning Kamp's avatar Poul-Henning Kamp

Add abi, major and minor to VMOD JSON spec

parent 419fbade
......@@ -54,10 +54,14 @@ struct vmod_import {
const char *err;
char *path;
// From $VMOD
double vmod_syntax;
char *name;
char *func_name;
char *file_id;
char *abi;
unsigned major;
unsigned minor;
struct symbol *sym;
const struct token *t_mod;
......@@ -102,31 +106,52 @@ vcc_ParseJSON(const struct vcc *tl, const char *jsn, struct vmod_import *vim)
return ("Not array[0]");
vv2 = VTAILQ_FIRST(&vv->children);
AN(vv2);
if (!vjsn_is_array(vv2))
return ("Not array[1]");
vv3 = VTAILQ_FIRST(&vv2->children);
AN(vv3);
if (!vjsn_is_string(vv3))
return ("Not string[2]");
if (strcmp(vv3->value, "$VMOD"))
return ("Not $VMOD[3]");
vv3 = VTAILQ_NEXT(vv3, list);
AN(vv3);
assert(vjsn_is_string(vv3));
vim->vmod_syntax = strtod(vv3->value, NULL);
assert (vim->vmod_syntax == 1.0);
vv3 = VTAILQ_NEXT(vv3, list);
AN(vv3);
assert(vjsn_is_string(vv3));
vim->name = vv3->value;
vv3 = VTAILQ_NEXT(vv3, list);
AN(vv3);
assert(vjsn_is_string(vv3));
vim->func_name = vv3->value;
vv3 = VTAILQ_NEXT(vv3, list);
AN(vv3);
assert(vjsn_is_string(vv3));
vim->file_id = vv3->value;
vv3 = VTAILQ_NEXT(vv3, list);
AN(vv3);
assert(vjsn_is_string(vv3));
vim->abi = vv3->value;
vv3 = VTAILQ_NEXT(vv3, list);
AN(vv3);
assert(vjsn_is_number(vv3));
vim->major = atoi(vv3->value);
vv3 = VTAILQ_NEXT(vv3, list);
AN(vv3);
assert(vjsn_is_number(vv3));
vim->minor = atoi(vv3->value);
if (!vcc_IdIs(vim->t_mod, vim->name)) {
VSB_printf(tl->sb, "Wrong file for VMOD %.*s\n",
PF(vim->t_mod));
......@@ -135,6 +160,27 @@ vcc_ParseJSON(const struct vcc *tl, const char *jsn, struct vmod_import *vim)
return ("");
}
if (vim->major == 0 && vim->minor == 0 &&
strcmp(vim->abi, VMOD_ABI_Version)) {
VSB_printf(tl->sb, "Incompatible VMOD %.*s\n", PF(vim->t_mod));
VSB_printf(tl->sb, "\tFile name: %s\n", vim->path);
VSB_printf(tl->sb, "\tABI mismatch, expected <%s>, got <%s>\n",
VMOD_ABI_Version, vim->abi);
return ("");
}
if (vim->major != 0 &&
(vim->major != VRT_MAJOR_VERSION ||
vim->minor > VRT_MINOR_VERSION)) {
VSB_printf(tl->sb, "Incompatible VMOD %.*s\n", PF(vim->t_mod));
VSB_printf(tl->sb, "\tFile name: %s\n", vim->path);
VSB_printf(tl->sb, "\tVMOD wants ABI version %u.%u\n",
vim->major, vim->minor);
VSB_printf(tl->sb, "\tvarnishd provides ABI version %u.%u\n",
VRT_MAJOR_VERSION, VRT_MINOR_VERSION);
return ("");
}
VTAILQ_FOREACH(vv2, &vv->children, list) {
assert (vjsn_is_array(vv2));
vv3 = VTAILQ_FIRST(&vv2->children);
......@@ -204,7 +250,9 @@ vcc_VmodLoad(const struct vcc *tl, struct vmod_import *vim, char *fnp)
return (-1);
}
err = vcc_ParseJSON(tl, vmd->json, vim);
assert(!memcmp(vmd->json, "VMOD_JSON_SPEC\x03", 15));
err = vcc_ParseJSON(tl, vmd->json + 15, vim);
AZ(dlclose(vim->hdl));
vim->hdl = NULL;
if (err != NULL && *err != '\0') {
......
......@@ -639,6 +639,12 @@ class ABIStanza(Stanza):
if self.vcc.strict_abi is None:
err("Valid ABI types are 'strict' or 'vrt', got '%s'\n" %
self.toks[1])
if self.vcc.strict_abi:
self.vcc.vrt_major = "0"
self.vcc.vrt_minor = "0"
else:
self.vcc.vrt_major = "VRT_MAJOR_VERSION"
self.vcc.vrt_minor = "VRT_MINOR_VERSION"
self.vcc.contents.append(self)
......@@ -1097,16 +1103,27 @@ class vcc(object):
yield i + " "
def json(self, fo, fnx):
fo.write('#define STRINGIFY(arg) #arg\n')
fo.write("\nstatic const char Vmod_Json[] = {\n")
fo.write('\t"VMOD_JSON_SPEC\\x03"\n')
for i in self.iter_json(fnx):
for n, i in enumerate(self.iter_json(fnx)):
fo.write('\t"')
for j in i:
if j in '"\\':
fo.write('\\')
fo.write(j)
fo.write('"\n')
if n == 6:
# Hand-munge the JSON to insert stuff only known by
# the C-compiler at compile-time.
fo.write(',"\n\t" \\"" VMOD_ABI_Version "\\", "\n')
fo.write('\t STRINGIFY(%s) ", "\n' % self.vrt_major)
fo.write('\t STRINGIFY(%s)\n' % self.vrt_minor)
else:
fo.write('"\n')
fo.write('\t\"\\n\"\n};\n')
fo.write('#undef STRINGIFY\n')
def vmod_data(self, fo):
vmd = "Vmod_%s_Data" % self.modname
......@@ -1115,12 +1132,8 @@ class vcc(object):
fo.write("/*lint -esym(%d, %s) */\n" % (i, vmd))
fo.write("\nextern const struct vmod_data %s;\n" % vmd)
fo.write("\nconst struct vmod_data %s = {\n" % vmd)
if self.strict_abi:
fo.write("\t.vrt_major =\t0,\n")
fo.write("\t.vrt_minor =\t0,\n")
else:
fo.write("\t.vrt_major =\tVRT_MAJOR_VERSION,\n")
fo.write("\t.vrt_minor =\tVRT_MINOR_VERSION,\n")
fo.write("\t.vrt_major =\t%s,\n" % self.vrt_major)
fo.write("\t.vrt_minor =\t%s,\n" % self.vrt_minor)
fo.write('\t.name =\t\t"%s",\n' % self.modname)
fo.write('\t.func =\t\t&%s,\n' % self.csn)
fo.write('\t.func_len =\tsizeof(%s),\n' % self.csn)
......
......@@ -1087,13 +1087,15 @@ const struct vmod_data Vmod_wrong2_Data = {
.func = foo_struct,
.func_len = sizeof foo_struct,
.func_name = "foo_struct",
.json = "["
.json = "VMOD_JSON_SPEC\x03["
"["
"\"$VMOD\""
", \"1.0\""
", \"wrongN\""
", \"foo_struct\""
", \"file_id\""
", \"abi\""
", 0, 0" // major, minor
"]"
"]",
};
......@@ -1106,13 +1108,15 @@ const struct vmod_data Vmod_wrong3_Data = {
.func = foo_struct,
.func_len = sizeof foo_struct,
.func_name = "foo_struct",
.json = "["
.json = "VMOD_JSON_SPEC\x03["
"["
"\"$VMOD\""
", \"1.0\""
", \"wrongN\""
", \"foo_struct\""
", \"file_id\""
", \"abi\""
", 0, 0" // major, minor
"]"
", [\"$CPROTO\", \"\"]"
"]",
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment