[master] 3f3ff59 Change the specification format in the compiled VMOD from our own home-rolled stuff to VJSN in anticipation of more complex specifications in the future.
Poul-Henning Kamp
phk at FreeBSD.org
Wed Feb 21 17:01:09 UTC 2018
commit 3f3ff599eeaf1c421d90605d6f40ce9d22e49390
Author: Poul-Henning Kamp <phk at FreeBSD.org>
Date: Wed Feb 21 16:58:49 2018 +0000
Change the specification format in the compiled VMOD from our own
home-rolled stuff to VJSN in anticipation of more complex
specifications in the future.
diff --git a/bin/varnishd/cache/cache_vrt_vmod.c b/bin/varnishd/cache/cache_vrt_vmod.c
index 658e3ba..4e11ce5 100644
--- a/bin/varnishd/cache/cache_vrt_vmod.c
+++ b/bin/varnishd/cache/cache_vrt_vmod.c
@@ -128,7 +128,7 @@ VRT_Vmod_Init(VRT_CTX, struct vmod **hdl, void *ptr, int len, const char *nm,
d->func == NULL ||
d->func_len <= 0 ||
d->proto == NULL ||
- d->spec == NULL) {
+ d->json == NULL) {
VSB_printf(ctx->msg,
"Loading VMOD %s from %s:\n", nm, path);
VSB_printf(ctx->msg, "VMOD data is mangled.\n");
diff --git a/include/vrt.h b/include/vrt.h
index c2dab1e..4822b9f 100644
--- a/include/vrt.h
+++ b/include/vrt.h
@@ -209,7 +209,7 @@ struct vmod_data {
const void *func;
int func_len;
const char *proto;
- const char * const *spec;
+ const char *json;
const char *abi;
};
diff --git a/lib/libvcc/vcc_compile.h b/lib/libvcc/vcc_compile.h
index 7ae776c..696aa6a 100644
--- a/lib/libvcc/vcc_compile.h
+++ b/lib/libvcc/vcc_compile.h
@@ -71,6 +71,7 @@ struct acl_e;
struct proc;
struct expr;
struct vcc;
+struct vjsn_val;
struct symbol;
struct source {
@@ -308,8 +309,8 @@ void vcc_Expr_Init(struct vcc *tl);
sym_expr_t vcc_Eval_Var;
sym_expr_t vcc_Eval_Handle;
sym_expr_t vcc_Eval_SymFunc;
-void vcc_Eval_Func(struct vcc *tl, const char *spec,
- const char *extra, const struct symbol *sym);
+void vcc_Eval_Func(struct vcc *, const struct vjsn_val *,
+ const char *, const struct symbol *);
void VCC_GlobalSymbol(struct symbol *, vcc_type_t fmt, const char *pfx);
struct symbol *VCC_HandleSymbol(struct vcc *, vcc_type_t , const char *);
diff --git a/lib/libvcc/vcc_expr.c b/lib/libvcc/vcc_expr.c
index f8e5d90..2191d4b 100644
--- a/lib/libvcc/vcc_expr.c
+++ b/lib/libvcc/vcc_expr.c
@@ -36,6 +36,7 @@
#include <string.h>
#include "vcc_compile.h"
+#include "vjsn.h"
struct expr {
unsigned magic;
@@ -400,7 +401,7 @@ vcc_priv_arg(struct vcc *tl, const char *p, const char *name, const char *vmod)
struct func_arg {
vcc_type_t type;
- const char *enum_bits;
+ const struct vjsn_val *enums;
const char *cname;
const char *name;
const char *val;
@@ -423,25 +424,20 @@ vcc_do_enum(struct vcc *tl, struct func_arg *fa, int len, const char *ptr)
static void
vcc_do_arg(struct vcc *tl, struct func_arg *fa)
{
- const char *p, *r;
struct expr *e2;
+ struct vjsn_val *vv;
if (fa->type == ENUM) {
ExpectErr(tl, ID);
ERRCHK(tl);
- r = p = fa->enum_bits;
- do {
- if (vcc_IdIs(tl->t, p))
+ VTAILQ_FOREACH(vv, &fa->enums->children, list)
+ if (vcc_IdIs(tl->t, vv->value))
break;
- p += strlen(p) + 1;
- } while (*p != '\1');
- if (*p == '\1') {
+ if (vv == NULL) {
VSB_printf(tl->sb, "Wrong enum value.");
VSB_printf(tl->sb, " Expected one of:\n");
- do {
- VSB_printf(tl->sb, "\t%s\n", r);
- r += strlen(r) + 1;
- } while (*r != '\0' && *r != '\1');
+ VTAILQ_FOREACH(vv, &fa->enums->children, list)
+ VSB_printf(tl->sb, "\t%s\n", vv->value);
vcc_ErrWhere(tl, tl->t);
return;
}
@@ -456,60 +452,59 @@ vcc_do_arg(struct vcc *tl, struct func_arg *fa)
}
static void
-vcc_func(struct vcc *tl, struct expr **e, const char *spec,
+vcc_func(struct vcc *tl, struct expr **e, const void *priv,
const char *extra, const struct symbol *sym)
{
vcc_type_t rfmt;
- const char *args;
const char *cfunc;
- const char *p;
struct expr *e1;
struct func_arg *fa, *fa2;
VTAILQ_HEAD(,func_arg) head;
struct token *t1;
+ const struct vjsn_val *vv, *vvp;
- rfmt = VCC_Type(spec);
- spec += strlen(spec) + 1;
- cfunc = spec;
- spec += strlen(spec) + 1;
- args = spec;
+ CAST_OBJ_NOTNULL(vv, priv, VJSN_VAL_MAGIC);
+ assert(vv->type == VJSN_ARRAY);
+ vv = VTAILQ_FIRST(&vv->children);
+ rfmt = VCC_Type(VTAILQ_FIRST(&vv->children)->value);
+ AN(rfmt);
+ vv = VTAILQ_NEXT(vv, list);
+ cfunc = vv->value;
+ vv = VTAILQ_NEXT(vv, list);
SkipToken(tl, '(');
- p = args;
if (extra == NULL)
extra = "";
- AN(rfmt);
VTAILQ_INIT(&head);
- while (*p != '\0') {
+ for(;vv != NULL; vv = VTAILQ_NEXT(vv, list)) {
+ assert(vv->type == VJSN_ARRAY);
fa = calloc(1, sizeof *fa);
AN(fa);
fa->cname = cfunc;
VTAILQ_INSERT_TAIL(&head, fa, list);
- if (!memcmp(p, "PRIV_", 5)) {
- fa->result = vcc_priv_arg(tl, p, sym->name, sym->vmod);
+
+ vvp = VTAILQ_FIRST(&vv->children);
+ if (!memcmp(vvp->value, "PRIV_", 5)) {
+ fa->result = vcc_priv_arg(tl, vvp->value,
+ sym->name, sym->vmod);
fa->name = "";
- p += strlen(p) + 1;
continue;
}
- fa->type = VCC_Type(p);
+ fa->type = VCC_Type(vvp->value);
AN(fa->type);
- p += strlen(p) + 1;
- if (*p == '\1') {
- fa->enum_bits = ++p;
- while (*p != '\1')
- p += strlen(p) + 1;
- p++;
- assert(*p == '\0');
- p++;
- }
- if (*p == '\2') {
- fa->name = p + 1;
- p += strlen(p) + 1;
- }
- if (*p == '\3') {
- fa->val = p + 1;
- p += strlen(p) + 1;
+ vvp = VTAILQ_NEXT(vvp, list);
+ if (vvp != NULL) {
+ fa->name = vvp->value;
+ vvp = VTAILQ_NEXT(vvp, list);
+ if (vvp != NULL) {
+ fa->val = vvp->value;
+ vvp = VTAILQ_NEXT(vvp, list);
+ if (vvp != NULL) {
+ fa->enums = vvp;
+ vvp = VTAILQ_NEXT(vvp, list);
+ }
+ }
}
- assert(*p == 0 || *p > ' ');
+ AZ(vvp);
}
VTAILQ_FOREACH(fa, &head, list) {
@@ -576,11 +571,12 @@ vcc_func(struct vcc *tl, struct expr **e, const char *spec,
SkipToken(tl, ')');
}
+
/*--------------------------------------------------------------------
*/
void
-vcc_Eval_Func(struct vcc *tl, const char *spec,
+vcc_Eval_Func(struct vcc *tl, const struct vjsn_val *spec,
const char *extra, const struct symbol *sym)
{
struct expr *e = NULL;
@@ -605,7 +601,6 @@ vcc_Eval_SymFunc(struct vcc *tl, struct expr **e, struct token *t,
assert(sym->kind == SYM_FUNC);
AN(sym->eval_priv);
- // assert(sym->fmt == VCC_Type(sym->eval_priv));
vcc_func(tl, e, sym->eval_priv, sym->extra, sym);
ERRCHK(tl);
if ((*e)->fmt == STRING) {
@@ -1261,7 +1256,7 @@ vcc_Act_Call(struct vcc *tl, struct token *t, struct symbol *sym)
struct expr *e;
e = NULL;
- vcc_Eval_SymFunc(tl, &e, t, sym, VOID);
+ vcc_func(tl, &e, sym->eval_priv, sym->extra, sym);
if (!tl->err) {
vcc_expr_fmt(tl->fb, tl->indent, e);
SkipToken(tl, ';');
diff --git a/lib/libvcc/vcc_vmod.c b/lib/libvcc/vcc_vmod.c
index 6b6969d..fe9253d 100644
--- a/lib/libvcc/vcc_vmod.c
+++ b/lib/libvcc/vcc_vmod.c
@@ -36,6 +36,7 @@
#include "libvcc.h"
#include "vfil.h"
+#include "vjsn.h"
#include "vmod_abi.h"
static int
@@ -54,18 +55,97 @@ vcc_path_dlopen(void *priv, const char *fn)
return (0);
}
+static void
+func_sym(struct symbol *sym, const char *vmod, const struct vjsn_val *v)
+{
+
+ assert(v->type == VJSN_ARRAY);
+ sym->action = vcc_Act_Call;
+ sym->vmod = vmod;
+ sym->eval = vcc_Eval_SymFunc;
+ sym->eval_priv = v;
+ v = VTAILQ_FIRST(&v->children);
+ assert(v->type == VJSN_ARRAY);
+ v = VTAILQ_FIRST(&v->children);
+ assert(v->type == VJSN_STRING);
+ sym->type = VCC_Type(v->value);
+ AN(sym->type);
+}
+
+static void
+parse_json(struct vcc * tl, const char *vmod, const char *json)
+{
+ struct inifin *ifp;
+ struct vjsn *vj;
+ struct vjsn_val *vv, *vv2;
+ double vmod_syntax = 0.0;
+ const char *p;
+ struct symbol *sym;
+
+ ifp = NULL;
+
+ vj = vjsn_parse(json, &p);
+ XXXAZ(p);
+ AN(vj);
+
+ VTAILQ_FOREACH(vv, &vj->value->children, list) {
+ assert(vv->type == VJSN_ARRAY);
+ vv2 = VTAILQ_FIRST(&vv->children);
+ assert(vv2->type == VJSN_STRING);
+ if (!strcmp(vv2->value, "$VMOD")) {
+ vmod_syntax =
+ strtod(VTAILQ_NEXT(vv2, list)->value, NULL);
+ continue;
+ }
+ assert (vmod_syntax == 1.0);
+ if (!strcmp(vv2->value, "$EVENT")) {
+ /* XXX: What about the rest of the events ? */
+ if (ifp == NULL)
+ ifp = New_IniFin(tl);
+ vv2 = VTAILQ_NEXT(vv2, list);
+ VSB_printf(ifp->ini,
+ "\tif (%s(ctx, &vmod_priv_%s, VCL_EVENT_LOAD))\n"
+ "\t\treturn(1);",
+ vv2->value, vmod);
+ VSB_printf(ifp->fin,
+ "\t\t(void)%s(ctx, &vmod_priv_%s,\n"
+ "\t\t\t VCL_EVENT_DISCARD);\n",
+ vv2->value, vmod);
+ VSB_printf(ifp->event, "%s(ctx, &vmod_priv_%s, ev)",
+ vv2->value, vmod);
+ } else if (!strcmp(vv2->value, "$FUNC")) {
+ vv2 = VTAILQ_NEXT(vv2, list);
+ sym = VCC_MkSym(tl,
+ vv2->value, SYM_FUNC, VCL_LOW, VCL_HIGH);
+ ERRCHK(tl);
+ AN(sym);
+ func_sym(sym, vmod, VTAILQ_NEXT(vv2, list));
+ } else if (!strcmp(vv2->value, "$OBJ")) {
+ vv2 = VTAILQ_NEXT(vv2, list);
+ sym = VCC_MkSym(tl, vv2->value,
+ SYM_OBJECT, VCL_LOW, VCL_HIGH);
+ XXXAN(sym);
+ sym->eval_priv = vv2;
+ sym->vmod = vmod;
+ } else {
+ VTAILQ_FOREACH(vv2, &vv->children, list)
+ fprintf(stderr, "\tt %s n %s v %s\n",
+ vv2->type, vv2->name, vv2->value);
+ WRONG("Vmod JSON syntax error");
+ }
+ }
+}
+
void
vcc_ParseImport(struct vcc *tl)
{
void *hdl;
char fn[1024], *fnp, *fnpx;
char buf[256];
+ const char *p;
struct token *mod, *t1;
struct inifin *ifp;
- const char * const *spec;
- struct symbol *sym;
struct symbol *msym;
- const char *p;
const struct vmod_data *vmd;
t1 = tl->t;
@@ -216,48 +296,7 @@ vcc_ParseImport(struct vcc *tl)
VSB_printf(ifp->fin, "\t\tVRT_priv_fini(&vmod_priv_%.*s);\n", PF(mod));
VSB_printf(ifp->fin, "\t\t\tVRT_Vmod_Fini(&VGC_vmod_%.*s);", PF(mod));
- ifp = NULL;
-
- spec = vmd->spec;
- for (; *spec != NULL; spec++) {
- p = *spec;
- if (!strcmp(p, "$OBJ")) {
- p += strlen(p) + 1;
- sym = VCC_MkSym(tl, p, SYM_OBJECT, VCL_LOW, VCL_HIGH);
- XXXAN(sym);
- sym->extra = p;
- sym->vmod = msym->name;
- } else if (!strcmp(p, "$EVENT")) {
- p += strlen(p) + 1;
- if (ifp == NULL)
- ifp = New_IniFin(tl);
- VSB_printf(ifp->ini,
- "\tif (%s(ctx, &vmod_priv_%.*s, VCL_EVENT_LOAD))\n"
- "\t\treturn(1);",
- p, PF(mod));
- VSB_printf(ifp->fin,
- "\t\t(void)%s(ctx, &vmod_priv_%.*s,\n"
- "\t\t\t VCL_EVENT_DISCARD);\n", p, PF(mod));
- VSB_printf(ifp->event, "%s(ctx, &vmod_priv_%.*s, ev)",
- p, PF(mod));
- } else if (!strcmp(p, "$FUNC")) {
- p += strlen(p) + 1;
- sym = VCC_MkSym(tl, p, SYM_FUNC, VCL_LOW, VCL_HIGH);
- ERRCHK(tl);
- AN(sym);
- sym->action = vcc_Act_Call;
- sym->vmod = msym->name;
- sym->eval = vcc_Eval_SymFunc;
- p += strlen(p) + 1;
- sym->eval_priv = p;
- sym->type = VCC_Type(p);
- AN(sym->type);
- } else {
- VSB_printf(tl->sb, "Internal spec error (%s)\n", p);
- vcc_ErrWhere(tl, mod);
- return;
- }
- }
+ parse_json(tl, msym->name, vmd->json);
Fh(tl, 0, "\n/* --- BEGIN VMOD %.*s --- */\n\n", PF(mod));
Fh(tl, 0, "static struct vmod *VGC_vmod_%.*s;\n", PF(mod));
@@ -271,9 +310,11 @@ vcc_Act_New(struct vcc *tl, struct token *t, struct symbol *sym)
{
struct symbol *sy1, *sy2, *sy3;
struct inifin *ifp;
- const char *p, *s_obj;
+ const char *s_obj;
char buf1[128];
char buf2[128];
+ const struct vjsn_val *vv, *vf;
+ const char *p;
(void)sym;
ExpectErr(tl, ID);
@@ -292,7 +333,7 @@ vcc_Act_New(struct vcc *tl, struct token *t, struct symbol *sym)
sy2 = VCC_SymbolGet(tl, SYM_OBJECT, "Symbol not found", XREF_NONE);
ERRCHK(tl);
AN(sy2);
- if (sy2->extra == NULL) {
+ if (sy2->eval_priv == NULL) {
VSB_printf(tl->sb, "Constructor not found: ");
vcc_ErrToken(tl, t);
VSB_printf(tl->sb, " at ");
@@ -300,49 +341,53 @@ vcc_Act_New(struct vcc *tl, struct token *t, struct symbol *sym)
return;
}
- p = sy2->extra;
- AN(p);
+ CAST_OBJ_NOTNULL(vv, sy2->eval_priv, VJSN_VAL_MAGIC);
+
+ s_obj = vv->value;
+ vv = VTAILQ_NEXT(vv, list);
+
+ Fh(tl, 0, "static %s *%s;\n\n", vv->value, sy1->rname);
+ vv = VTAILQ_NEXT(vv, list);
- s_obj = p;
- p += strlen(p) + 1;
+ vf = VTAILQ_FIRST(&vv->children);
+ vv = VTAILQ_NEXT(vv, list);
+ assert(vf->type == VJSN_STRING);
+ assert(!strcmp(vf->value, "$INIT"));
- Fh(tl, 0, "static %s *%s;\n\n", p, sy1->rname);
- p += strlen(p) + 1;
+ vf = VTAILQ_NEXT(vf, list);
bprintf(buf1, ", &%s, \"%s\"", sy1->rname, sy1->name);
- vcc_Eval_Func(tl, p, buf1, sy2);
+ vcc_Eval_Func(tl, vf, buf1, sy2);
ERRCHK(tl);
SkipToken(tl, ';');
+ sy1->def_e = tl->t;
- while (p[0] != '\0' || p[1] != '\0' || p[2] != '\0')
- p++;
- p += 3;
+ vf = VTAILQ_FIRST(&vv->children);
+ vv = VTAILQ_NEXT(vv, list);
+ assert(vf->type == VJSN_STRING);
+ assert(!strcmp(vf->value, "$FINI"));
+ vf = VTAILQ_NEXT(vf, list);
+ vf = VTAILQ_FIRST(&vf->children);
+ vf = VTAILQ_NEXT(vf, list);
ifp = New_IniFin(tl);
- p += strlen(p) + 1;
- VSB_printf(ifp->fin, "\t\t%s(&%s);", p, sy1->rname);
-
- while (p[0] != '\0' || p[1] != '\0' || p[2] != '\0')
- p++;
- p += 3;
+ VSB_printf(ifp->fin, "\t\t%s(&%s);", vf->value, sy1->rname);
/* Instantiate symbols for the methods */
bprintf(buf1, ", %s", sy1->rname);
- while (*p != '\0') {
- p += strlen(s_obj);
- bprintf(buf2, "%s%s", sy1->name, p);
+ p = TlDup(tl, buf1);
+ while (vv != NULL) {
+ vf = VTAILQ_FIRST(&vv->children);
+ assert(vf->type == VJSN_STRING);
+ assert(!strcmp(vf->value, "$METHOD"));
+ vf = VTAILQ_NEXT(vf, list);
+ assert(vf->type == VJSN_STRING);
+
+ bprintf(buf2, "%s%s", sy1->name, vf->value + strlen(s_obj));
sy3 = VCC_MkSym(tl, buf2, SYM_FUNC, VCL_LOW, VCL_HIGH);
AN(sy3);
- sy3->action = vcc_Act_Call;
- sy3->eval = vcc_Eval_SymFunc;
- p += strlen(p) + 1;
- sy3->eval_priv = p;
- sy3->type = VCC_Type(p);
- sy3->extra = TlDup(tl, buf1);
- sy3->vmod = sy2->vmod;
- while (p[0] != '\0' || p[1] != '\0' || p[2] != '\0')
- p++;
- p += 3;
+ func_sym(sy3, sy2->vmod, VTAILQ_NEXT(vf, list));
+ sy3->extra = p;
+ vv = VTAILQ_NEXT(vv, list);
}
- sy1->def_e = tl->t;
}
diff --git a/lib/libvcc/vmodtool.py b/lib/libvcc/vmodtool.py
index dad08a8..b5ea510 100755
--- a/lib/libvcc/vmodtool.py
+++ b/lib/libvcc/vmodtool.py
@@ -43,6 +43,7 @@ import optparse
import unittest
import random
import copy
+import json
rstfmt = False
strict_abi = True
@@ -227,24 +228,10 @@ class ctype(object):
return self.vt
return self.vt + " {" + ",".join(self.spec) + "}"
- def specstr(self, fo, p):
- fo.write(p + '"' + self.vt)
- fo.write('\\0"\n')
- p = indent(p, 4)
- if self.spec is not None:
- fo.write(p + '"\\1"\n')
- p = indent(p, 4)
- for i in self.spec:
- fo.write(p + '"' + i + '\\0"\n')
- p = indent(p, -4)
- # This terminating \1 is necessary to ensure that
- # a prototype always ends with three \0's
- fo.write(p + '"\\1\\0"\n')
- if self.nm is not None:
- fo.write(p + '"\\2" "' + self.nm + '\\0"\n')
- if self.defval is not None:
- fo.write(p + '"\\3" "' + quote(self.defval) + '\\0"\n')
-
+ def json(self, jl):
+ jl.append([self.vt, self.nm, self.defval, self.spec])
+ while jl[-1][-1] is None:
+ jl[-1].pop(-1)
def vtype(txt):
j = len(txt)
@@ -404,17 +391,13 @@ class prototype(object):
s += '%s %s(%s);' % (self.c_ret(), fn, self.c_args(args))
return "\n".join(lwrap(s)) + "\n"
- def specstr(self, fo, cfunc, p):
- if self.retval is None:
- fo.write(p + '"VOID\\0"\n')
- else:
- self.retval.specstr(fo, p)
- fo.write(p + '"' + cfunc + '\\0"\n')
- p = indent(p, 4)
- if self.args is not None:
- for i in self.args:
- i.specstr(fo, p)
- fo.write(p + '"\\0"\n')
+ def json(self, jl, cfunc):
+ ll = []
+ self.retval.json(ll)
+ ll.append(cfunc)
+ for i in self.args:
+ i.json(ll)
+ jl.append(ll)
#######################################################################
@@ -469,7 +452,7 @@ class stanza(object):
def cstruct_init(self, fo):
return
- def specstr(self, fo):
+ def json(self, jl):
return
#######################################################################
@@ -568,10 +551,11 @@ class s_event(stanza):
def cstruct_init(self, fo):
fo.write("\t%s,\n" % self.event_func)
- def specstr(self, fo):
- fo.write('\t"$EVENT\\0"\n\t "Vmod_%s_Func._event",\n\n' %
- self.vcc.modname)
-
+ def json(self, jl):
+ jl.append([
+ "$EVENT",
+ "Vmod_%s_Func._event" % self.vcc.modname
+ ])
class s_function(stanza):
def parse(self):
@@ -591,12 +575,13 @@ class s_function(stanza):
def cstruct_init(self, fo):
fo.write("\t" + self.proto.cname(pfx=True) + ",\n")
- def specstr(self, fo):
- fo.write('\t"$FUNC\\0"\t"%s.%s\\0"\n\n' %
- (self.vcc.modname, self.proto.name))
- self.proto.specstr(fo, 'Vmod_%s_Func.%s' %
- (self.vcc.modname, self.proto.cname()), "\t ")
- fo.write('\t "\\0",\n\n')
+ def json(self,jl):
+ jl.append([
+ "$FUNC",
+ "%s.%s" % (self.vcc.modname, self.proto.name),
+ ])
+ self.proto.json(jl[-1], 'Vmod_%s_Func.%s' %
+ (self.vcc.modname, self.proto.cname()))
class s_object(stanza):
@@ -663,29 +648,29 @@ class s_object(stanza):
i.cstruct_init(fo)
fo.write("\n")
- def specstr(self, fo):
+ def json(self, jl):
+ ll = [
+ "$OBJ",
+ self.vcc.modname + "." + self.proto.name,
+ "struct %s%s_%s" %
+ (self.vcc.sympfx, self.vcc.modname, self.proto.name),
+ ]
- fo.write('\t"$OBJ\\0"\t"%s.%s\\0"\n\n' %
- (self.vcc.modname, self.proto.name))
+ l2 = [ "$INIT" ]
+ ll.append(l2)
+ self.init.json(l2,
+ 'Vmod_%s_Func.%s' % (self.vcc.modname, self.init.name))
- fo.write('\t "struct %s%s_%s\\0"\n' %
- (self.vcc.sympfx, self.vcc.modname, self.proto.name))
- fo.write("\n")
-
- self.proto.specstr(fo, 'Vmod_%s_Func.%s' %
- (self.vcc.modname, self.init.name), '\t ')
- fo.write('\t "\\0"\n\n')
-
- fo.write('\t "VOID\\0"\n')
- fo.write('\t "Vmod_%s_Func.%s\\0"\n' %
- (self.vcc.modname, self.fini.name))
- fo.write('\t\t"\\0"\n')
- fo.write('\t "\\0"\n\n')
+ l2 = [ "$FINI" ]
+ ll.append(l2)
+ self.fini.json(l2,
+ 'Vmod_%s_Func.%s' % (self.vcc.modname, self.fini.name))
for i in self.methods:
- i.specstr(fo)
+ i.json(ll)
+
+ jl.append(ll)
- fo.write('\t "\\0",\n\n')
def dump(self):
super(s_object, self).dump()
@@ -707,12 +692,14 @@ class s_method(stanza):
def cstruct_init(self, fo):
fo.write('\t' + self.proto.cname(pfx=True) + ",\n")
- def specstr(self, fo):
- fo.write('\t "%s.%s\\0"\n' %
- (self.vcc.modname, self.proto.name))
- self.proto.specstr(fo, 'Vmod_%s_Func.%s' %
- (self.vcc.modname, self.proto.cname()), '\t\t')
- fo.write('\t\t"\\0"\n\n')
+ def json(self, jl):
+ jl.append([
+ "$METHOD",
+ self.vcc.modname + "." + self.proto.name
+ ])
+ self.proto.json(jl[-1],
+ 'Vmod_%s_Func.%s' % (self.vcc.modname, self.proto.cname()))
+
#######################################################################
@@ -836,15 +823,29 @@ class vcc(object):
fo.write("\t&%senum_%s,\n" % (self.sympfx, j))
fo.write("};\n")
- def specstr(self, fo):
- fo.write("\n/*lint -save -e786 -e840 */\n")
- fo.write("static const char * const Vmod_Spec[] = {\n")
-
+ def json(self, fo):
+ jl = [ ["$VMOD", "1.0" ] ]
for j in self.contents:
- j.specstr(fo)
- fo.write("\t0\n")
- fo.write("};\n")
- fo.write("/*lint -restore */\n")
+ j.json(jl)
+
+ bz = bytearray(json.dumps(jl, separators=(",",":"))) + "\0"
+ fo.write("\nstatic const char Vmod_Json[%d] = {\n" % len(bz))
+ t = "\t"
+ for i in bz:
+ t += "%d," % i
+ if len(t) >= 69:
+ fo.write(t + "\n")
+ t = "\t"
+ if len(t) > 1:
+ fo.write(t[:-1])
+ fo.write("\n};\n\n")
+ for i in json.dumps(jl, indent=2, separators=(',', ': ')).split("\n"):
+ j = "// " + i
+ if len(j) > 72:
+ fo.write(j[:72] + "[...]\n")
+ else:
+ fo.write(j + "\n")
+ fo.write("\n")
def api(self, fo):
for i in (714, 759, 765):
@@ -863,7 +864,7 @@ class vcc(object):
fo.write('\t.func =\t\t&Vmod_Func,\n')
fo.write('\t.func_len =\tsizeof(Vmod_Func),\n')
fo.write('\t.proto =\tVmod_Proto,\n')
- fo.write('\t.spec =\t\tVmod_Spec,\n')
+ fo.write('\t.json =\t\tVmod_Json,\n')
fo.write('\t.abi =\t\tVMOD_ABI_Version,\n')
# NB: Sort of hackish:
# Fill file_id with random stuff, so we can tell if
@@ -927,7 +928,7 @@ class vcc(object):
os.remove(fn2)
- self.specstr(fo)
+ self.json(fo)
self.api(fo)
More information about the varnish-commit
mailing list