Commit b94f433d by Nils Goroll

replace enum parsing with vmod_enum_ and table files

parent c916614c
......@@ -96,8 +96,6 @@ AC_PATH_PROG([VARNISHTEST], [varnishtest], [],
AC_PATH_PROG([VARNISHD], [varnishd], [],
[$LIBVARNISHAPI_SBINDIR:$LIBVARNISHAPI_BINDIR:$PATH])
AC_PATH_PROG([PERL], [perl])
# --enable-stack-protector
AC_ARG_ENABLE(stack-protector,
AS_HELP_STRING([--enable-stack-protector],[enable stack protector (default is YES)]),
......
......@@ -8,6 +8,8 @@ libvmod_blobdigest_la_LDFLAGS = -module -export-dynamic -avoid-version -shared
libvmod_blobdigest_la_SOURCES = \
vmod_blobdigest.h \
vmod_blobdigest.c \
tbl_scope.h \
tbl_algorithm.h \
byte_order.h \
byte_order.c \
crc32.h \
......@@ -25,16 +27,9 @@ libvmod_blobdigest_la_SOURCES = \
nodist_libvmod_blobdigest_la_SOURCES = \
vcc_if.c \
vcc_if.h \
parse_algorithm.h \
parse_algorithm.c
vcc_if.h
parse_algorithm.h: parse_algorithm.c
parse_algorithm.c: gen_enum_parse.pl
@PERL@ $(srcdir)/gen_enum_parse.pl parse_algorithm.c parse_algorithm.h
vmod_blobdigest.lo: vcc_if.c vcc_if.h parse_algorithm.h
vmod_blobdigest.lo: vcc_if.c vcc_if.h
vcc_if.c: vcc_if.h
......@@ -51,7 +46,6 @@ $(top_srcdir)/src/tests/*.vtc: libvmod_blobdigest.la
check: $(VMOD_TESTS)
EXTRA_DIST = \
gen_enum_parse.pl \
vmod_blobdigest.vcc \
$(VMOD_TESTS)
......@@ -59,6 +53,4 @@ CLEANFILES = \
$(builddir)/vcc_if.c \
$(builddir)/vcc_if.h \
$(builddir)/vmod_blobdigest.rst \
$(builddir)/vmod_blobdigest.man.rst \
$(builddir)/parse_algorithm.h \
$(builddir)/parse_algorithm.c
$(builddir)/vmod_blobdigest.man.rst
#!/usr/bin/perl
use strict;
use warnings;
my @vals = (qw(
CRC32
MD5
SHA1
SHA224
SHA256
SHA384
SHA512
SHA3_224
SHA3_256
SHA3_384
SHA3_512
));
sub assert {
unless($_[0]) {
require Carp;
Carp::confess();
}
return undef;
}
sub _OUT {
my $fd = shift;
print $fd @_;
}
sub parse_token_code_gen {
my $fd = shift;
my $prevpos = shift; # 0, 1 ...
my $prev = shift; # "G", "GE", ...
my $term = shift; # function(macro) name to check if a symbol is terminator
assert ((scalar(@_) % 2) == 0);
my %symbs = @_; # symbol => result, ...
my $pos = $prevpos + 1;
# label
if ($prevpos != -1) {
_OUT ($fd, ' _'.$prevpos.$prev.":\n");
}
my $nsymbs = scalar(keys %symbs);
assert ($nsymbs);
if ($nsymbs == 1) {
my ($m, $r) = %symbs;
my @cond;
# optimize for just this one string
my $i;
for ($i = $pos; $i < length($m); $i++) {
push @cond, '(m['.$i."] == '".substr($m, $i, 1)."')";
}
push @cond, '('.$term.'(m['.$i."]))";
_OUT ($fd, "\t//".$m."\n");
_OUT ($fd, "\t".'if ('.join(" && ", @cond).') {'."\n");
_OUT ($fd, "\t".' r = '.$r.";\n");
_OUT ($fd, "\t".' p = '.$i.";\n");
_OUT ($fd, "\t".' goto ok;'."\n");
_OUT ($fd, "\t"."}\n");
_OUT ($fd, "\t".'goto invalid;'."\n");
} else {
my @case;
my @tocall;
{
## terminating keys
foreach my $m (grep { (length($_) == $pos) } sort keys %symbs) {
my $r = delete $symbs{$m};
_OUT ($fd, "\t//".$m."\n");
_OUT ($fd, "\t".'if ('.$term.'(m['.$pos.'])) {'."\n");
_OUT ($fd, "\t".' r = '.$r.";\n");
_OUT ($fd, "\t".' p = '.$pos.";\n");
_OUT ($fd, "\t".' goto ok;'."\n");
_OUT ($fd, "\t"."}\n");
}
}
{
## non-terminating keys
my @keys = (sort keys %symbs);
# hash by this char
my %h;
foreach my $k (@keys) {
assert( length($k) > $pos );
push @{$h{substr($k, $pos, 1)}}, ($k);
}
foreach my $k (sort keys %h) {
my $la = '_'.$pos.$prev.$k;
my @me = @{$h{$k}};
push @case, ("case '".$k."':\tgoto ".$la.";\t// ".
join(", ",@me));
push @tocall, [$prev.$k, \@me];
}
}
push @case, ("default:\tgoto invalid;");
_OUT ($fd, "\t".'switch (m['.$pos."]) {\n\t");
_OUT ($fd, join("\n\t", @case)."\n");
_OUT ($fd, "\t}\n");
if (scalar(@tocall)) {
map {
parse_token_code_gen($fd, $pos, $_->[0],
$term,
(map { $_ => $symbs{$_}; }
@{$_->[1]}));
} @tocall;
}
}
}
unless ($#ARGV == 1) {
printf(STDERR 'Usage: '.$0." <c-file> <h-file>\n");
exit 1;
}
my ($c_file, $h_file) = @ARGV;
open(my $c_out, '>', $c_file) || die('cannot open '.$c_file.': '.$!);
open(my $h_out, '>', $h_file) || die('cannot open '.$h_file.': '.$!);
_OUT($h_out, <<'EOF');
/* AUTO-GENERATED, DO NOT EDIT */
EOF
_OUT($h_out,
"enum algorithm {\n\t_INVALID = 0,\n\t".
join(",\n\t", @vals).",\n\t__MAX_ALGORITHM\n};\n");
_OUT($h_out, <<'EOF');
enum algorithm parse_algorithm (const char *);
EOF
_OUT($c_out, <<EOF);
/* AUTO-GENERATED, DO NOT EDIT */
#include "$h_file"
#define term(c) ((c) == '\\0')
EOF
_OUT($c_out, <<'EOF');
enum algorithm
parse_algorithm (const char *m) {
int p;
enum algorithm r;
EOF
parse_token_code_gen($c_out, -1, '', 'term',
map { ($_ => $_) } @vals);
_OUT($c_out, <<EOF);
ok:
return r;
invalid:
return _INVALID;
(void)p;
}
EOF
close($c_out) || die('error closing '.$c_file.': '.$!);
close($h_out) || die('error closing '.$h_file.': '.$!);
VMODENUM(CRC32)
VMODENUM(MD5)
VMODENUM(SHA1)
VMODENUM(SHA224)
VMODENUM(SHA256)
VMODENUM(SHA384)
VMODENUM(SHA512)
VMODENUM(SHA3_224)
VMODENUM(SHA3_256)
VMODENUM(SHA3_384)
VMODENUM(SHA3_512)
#undef VMODENUM
VMODENUM(TASK)
VMODENUM(TOP)
#undef VMODENUM
......@@ -61,12 +61,6 @@ struct digest_task {
struct vmod_priv *result;
};
enum scope {
_SCOPE_INVALID = 0,
PRIV_TASK,
PRIV_TOP
};
struct vmod_blobdigest_digest {
unsigned magic;
#define VMOD_BLOBDIGEST_DIGEST_MAGIC 0xaccb2e25
......@@ -86,6 +80,22 @@ struct vmod_blobdigest_hmac {
enum algorithm hash;
};
static enum algorithm
parse_algorithm(VCL_ENUM e)
{
#define VMODENUM(n) if (e == vmod_enum_ ## n) return(n);
#include "tbl_algorithm.h"
WRONG("illegal algorithm enum");
}
static enum scope
parse_scope(VCL_ENUM e)
{
#define VMODENUM(n) if (e == vmod_enum_ ## n) return(n);
#include "tbl_scope.h"
WRONG("illegal scope enum");
}
static void
init(const enum algorithm hash, hash_ctx * const hctx)
{
......@@ -251,11 +261,11 @@ get_scope(const struct vrt_ctx * const restrict ctx,
struct ws *ws;
switch (h->scope) {
case PRIV_TASK:
case TASK:
priv = VRT_priv_task(ctx, (void *)h);
ws = ctx->ws;
break;
case PRIV_TOP: {
case TOP: {
if (ctx->req == NULL) {
VERR(ctx, "%s.%s(): object has TOP scope - only "
"accessible in client VCL context",
......@@ -296,18 +306,6 @@ get_scope(const struct vrt_ctx * const restrict ctx,
return task;
}
static inline enum scope
parse_scope(const char * const restrict p)
{
assert(p[0] == 'T');
if (p[1] == 'O') {
assert(p[2] == 'P');
return PRIV_TOP;
}
assert(p[1] == 'A' && p[2] == 'S' && p[3] == 'K');
return PRIV_TASK;
}
VCL_VOID
vmod_digest__init(VRT_CTX, struct vmod_blobdigest_digest **digestp,
const char *vcl_name, VCL_ENUM hashs, VCL_BLOB initb,
......
......@@ -27,7 +27,6 @@
#include <sys/types.h>
#include "parse_algorithm.h"
#include "crc32.h"
#include "md5.h"
#include "sha1.h"
......@@ -38,6 +37,20 @@
#define SHA3_BLOCKSZ(bits) ((1600 - (bits) * 2) / 8)
enum algorithm {
_ALGORITHM_INVALID = 0,
#define VMODENUM(x) x,
#include "tbl_algorithm.h"
__MAX_ALGORITHM
};
enum scope {
_SCOPE_INVALID = 0,
#define VMODENUM(x) x,
#include "tbl_scope.h"
__MAX_SCOPE
};
typedef union hash_ctx {
uint32_t crc32;
md5_ctx md5;
......
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