Commit 3610d8f1 authored by Poul-Henning Kamp's avatar Poul-Henning Kamp

Add the outline of the VMOD "std" which will in the future contain

the standard functions supported in VCC.

For now put the very magic python script that ties the C code to the
VCL typesystem and the VCC compiler here.  Eventually it goes elsewere.


git-svn-id: http://www.varnish-cache.org/svn/trunk/varnish-cache@5145 d4fa192b-c00b-0410-8231-f00ffab90ce4
parent f9709cc9
......@@ -5,6 +5,7 @@ SUBDIRS = \
libvarnish \
libvarnishapi \
libvcl \
libvmod_std \
@JEMALLOC_SUBDIR@
DIST_SUBDIRS = \
......@@ -12,4 +13,5 @@ DIST_SUBDIRS = \
libvarnish \
libvarnishapi \
libvcl \
libvmod_std \
libjemalloc
......@@ -28,6 +28,7 @@ libvcl_la_SOURCES = \
vcc_symb.c \
vcc_token.c \
vcc_var.c \
vcc_vmod.c \
vcc_xref.c
EXTRA_DIST = \
......
......@@ -189,7 +189,7 @@ Ff(const struct vcc *tl, int indent, const char *fmt, ...)
/*--------------------------------------------------------------------*/
static void
void
EncString(struct vsb *sb, const char *b, const char *e, int mode)
{
......
......@@ -212,6 +212,7 @@ void Ff(const struct vcc *tl, int indent, const char *fmt, ...);
void EncToken(struct vsb *sb, const struct token *t);
int IsMethod(const struct token *t);
void *TlAlloc(struct vcc *tl, unsigned len);
void EncString(struct vsb *sb, const char *b, const char *e, int mode);
/* vcc_dir_random.c */
parsedirector_f vcc_ParseRandomDirector;
......@@ -269,6 +270,9 @@ const struct var *vcc_FindVar(struct vcc *tl, const struct token *t,
void vcc_VarVal(struct vcc *tl, const struct var *vp,
const struct token *vt);
/* vcc_vmod.c */
void vcc_ParseImport(struct vcc *tl);
/* vcc_xref.c */
void vcc_AddDef(struct vcc *tl, struct token *t, enum ref_type type);
void vcc_AddRef(struct vcc *tl, struct token *t, enum ref_type type);
......
......@@ -261,6 +261,7 @@ static struct toplev {
{ "backend", vcc_ParseDirector },
{ "director", vcc_ParseDirector },
{ "probe", vcc_ParseProbe },
{ "import", vcc_ParseImport },
{ NULL, NULL }
};
......
/*-
* Copyright (c) 2010 Linpro AS
* All rights reserved.
*
* Author: Poul-Henning Kamp <phk@phk.freebsd.dk>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* 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.
*/
#include "config.h"
#include "svnid.h"
SVNID("$Id$");
#include <stdio.h>
#include <dlfcn.h>
#include "vsb.h"
#include "vcc_priv.h"
#include "vcc_compile.h"
#include "libvarnish.h"
void
vcc_ParseImport(struct vcc *tl)
{
void *hdl;
char fn[1024];
struct token *mod;
const char *modname;
const char *proto;
// int *modlen;
SkipToken(tl, ID);
ExpectErr(tl, ID);
mod = tl->t;
vcc_NextToken(tl);
if (tl->t->tok == ID) {
vcc_NextToken(tl);
ExpectErr(tl, CSTR);
bprintf(fn, "%s", tl->t->dec);
vcc_NextToken(tl);
} else {
Fi(tl, 0, ", NULL);\n");
bprintf(fn, "XXX: %s", "XXX: no default path");
}
Fh(tl, 0, "static void *VGC_vmod_%.*s;\n", PF(mod));
Fi(tl, 0, "\tVRT_Vmod_Init(&VGC_vmod_%.*s,\n", PF(mod));
Fi(tl, 0, "\t &Vmod_Func_%.*s,\n", PF(mod));
Fi(tl, 0, "\t sizeof(Vmod_Func_%.*s),\n", PF(mod));
Fi(tl, 0, "\t \"%.*s\",\n", PF(mod));
if (fn != NULL) {
Fi(tl, 0, "\t ");
EncString(tl->fi, fn, NULL, 0);
} else {
Fi(tl, 0, "\t 0");
}
Fi(tl, 0, ");\n");
/* XXX: zero the function pointer structure */
Ff(tl, 0, "\tVRT_Vmod_Fini(&VGC_vmod_%.*s);\n", PF(mod));
SkipToken(tl, ';');
hdl = dlopen(fn, RTLD_NOW | RTLD_LOCAL);
if (hdl == NULL) {
vsb_printf(tl->sb, "Could not load module %.*s\n\t%s\n\t%s\n",
PF(mod), fn, dlerror());
vcc_ErrWhere(tl, mod);
return;
}
modname = dlsym(hdl, "Vmod_Name");
if (modname == NULL) {
vsb_printf(tl->sb, "Could not load module %.*s\n\t%s\n\t%s\n",
PF(mod), fn, "Symbol Vmod_Name not found");
vcc_ErrWhere(tl, mod);
return;
}
if (!vcc_IdIs(mod, modname)) {
vsb_printf(tl->sb, "Could not load module %.*s\n\t%s\n",
PF(mod), fn);
vsb_printf(tl->sb, "\tModule has wrong name: <%s>\n", modname);
vcc_ErrWhere(tl, mod);
return;
}
proto = dlsym(hdl, "Vmod_Proto");
if (modname == NULL) {
vsb_printf(tl->sb, "Could not load module %.*s\n\t%s\n\t%s\n",
PF(mod), fn, "Symbol Vmod_Proto not found");
vcc_ErrWhere(tl, mod);
return;
}
Fh(tl, 0, "\n%s\n", proto);
}
# $Id$
INCLUDES = -I$(top_srcdir)/include
lib_LTLIBRARIES = libvmod_std.la
libvmod_std_la_LDFLAGS = -version-info 1:0:0
libvmod_std_la_SOURCES = \
$(builddir)/vmod.c \
vmod_std.c
$(builddir)/vmod.c $(builddir)/vmod.h: $(top_srcdir)/lib/libvmod_std/vmod.py $(top_srcdir)/lib/libvmod_std/vmod.spec
@PYTHON@ $(top_srcdir)/lib/libvmod_std/vmod.py $(top_srcdir)/lib/libvmod_std/vmod.spec
EXTRA_DIST = vmod.py
CLEANFILES = $(builddir)/vmod.c $(builddir)/vmod.h
#!/usr/local/bin/python
#-
# Copyright (c) 2010 Linpro AS
# All rights reserved.
#
# Author: Poul-Henning Kamp <phk@phk.freebsd.dk>
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# 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.
#
# Read the vmod.spec file and produce the vmod.h and vmod.c files.
#
# vmod.h contains the prototypes for the published functions, the module
# C-code should include this file to ensure type-consistency.
#
# vmod.c contains the symbols which VCC and varnishd will use to access
# the module: A structure of properly typed function pointers, the
# size of this structure in bytes, and the definition of the structure
# as a string, suitable for inclusion in the C-source of the compile VCL
# program.
#
# $Id$
import sys
if len(sys.argv) == 2:
specfile = sys.argv[1]
else:
specfile = "vmod.psec"
type_tab = dict()
type_tab['VOID'] = "V"
type_tab['REAL'] = "R"
type_tab['STRING'] = "S"
type_tab['STRING_LIST'] = "L"
ctypes = {
'IP': "struct sockaddr *",
'STRING': "const char *",
'STRING_LIST': "const char *, ...",
'BOOL': "unsigned",
'BACKEND': "struct director *",
'TIME': "double",
'REAL': "double",
'DURATION': "double",
'INT': "int",
'HEADER': "const char *",
}
#######################################################################
modname = "???"
pstruct = ""
pinit = ""
tdl = ""
plist = ""
def do_func(fname, rval, args):
global pstruct
global pinit
global plist
global tdl
print(fname, rval, args)
proto = ctypes[rval] + " vmod_" + fname + "("
sproto = ctypes[rval] + " td_" + fname + "("
s=""
for i in args:
proto += s + ctypes[i]
sproto += s + ctypes[i]
s = ", "
proto += ")"
sproto += ")"
plist += proto + ";\n"
tdl += "typedef\t" + sproto + ";\n"
pstruct += "\ttd_" + fname + "\t*" + fname + ";\n"
pinit += "\tvmod_" + fname + ",\n"
#######################################################################
f = open(specfile, "r")
for l0 in f:
# print("# " + l0)
i = l0.find("#")
if i == 0:
continue
if i >= 0:
line = l0[:i-1]
else:
line = l0
line = line.expandtabs().strip()
l = line.partition(" ")
if l[0] == "Module":
modname = l[2].strip();
continue
if l[0] != "Function":
assert False
l = l[2].strip().partition(" ")
rt_type = l[0]
l = l[2].strip().partition("(")
fname = l[0].strip()
args = list()
while True:
l = l[2].strip().partition(",")
if len(l[2]) == 0:
break
args.append(l[0])
l = l[0].strip().partition(")")
args.append(l[0])
do_func(fname, rt_type, args)
#######################################################################
def dumps(s):
while True:
l = s.partition("\n")
if len(l[0]) == 0:
break
fc.write('\t"' + l[0] + '\\n"\n')
s = l[2]
#######################################################################
fc = open("vmod.c", "w")
fh = open("vmod.h", "w")
fh.write(plist)
fc.write('#include "vmod.h"\n')
fc.write("\n");
fc.write(tdl);
fc.write("\n");
fc.write("const struct Vmod_Func_" + modname + " {\n")
fc.write(pstruct + "} Vmod_Func = {\n" + pinit + "};\n")
fc.write("\n");
fc.write("const int Vmod_Len = sizeof(Vmod_Func);\n")
fc.write("\n");
fc.write('const char Vmod_Proto[] = \n')
dumps(tdl);
fc.write('\t"\\n"\n')
dumps("struct Vmod_Func_" + modname + " {\n")
dumps(pstruct + "} Vmod_Func_" + modname + ";\n")
fc.write('\t;\n')
fc.write("\n");
fc.write('const char Vmod_Name[] = "' + modname + '";\n')
Module std
Function STRING toupper(STRING_LIST)
Function STRING tolower ( STRING_LIST)
Function REAL real(STRING, REAL)
#include "vmod.h"
const char *
vmod_toupper(const char *s, ...)
{
(void)s;
return ("UPPER");
}
const char *
vmod_tolower(const char *s, ...)
{
(void)s;
return ("LOWER");
}
double
vmod_real(const char *s, double d)
{
(void)s;
(void)d;
return (3.1415);
}
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