wireshark/epan/wslua/make-taps.pl

223 lines
5.0 KiB
Perl
Executable File

#!/usr/bin/perl
#
# make-taps.pl
# Extract structs from C headers to generate a function that
# pushes a lua table into the stack containing the elements of
# the struct.
#
# (c) 2006 Luis E. Garcia Ontanon <luis@ontanon.org>
#
# Wireshark - Network traffic analyzer
# By Gerald Combs <gerald@wireshark.org>
# Copyright 2006 Gerald Combs
#
# SPDX-License-Identifier: GPL-2.0-or-later
use strict;
use warnings;
my %types = %{{
'gchar[]' => 'lua_pushstring(L,(const char*)v->STR);',
'gchar*' => 'lua_pushstring(L,(const char*)v->STR);',
'guint' => 'lua_pushnumber(L,(lua_Number)v->STR);',
'guint8' => 'lua_pushnumber(L,(lua_Number)v->STR);',
'guint16' => 'lua_pushnumber(L,(lua_Number)v->STR);',
'guint32' => 'lua_pushnumber(L,(lua_Number)v->STR);',
'gint' => 'lua_pushnumber(L,(lua_Number)v->STR);',
'gint8' => 'lua_pushnumber(L,(lua_Number)v->STR);',
'gint16' => 'lua_pushnumber(L,(lua_Number)v->STR);',
'gint32' => 'lua_pushnumber(L,(lua_Number)v->STR);',
'gboolean' => 'lua_pushboolean(L,(int)v->STR);',
'address' => '{ Address a = (Address)g_malloc(sizeof(address)); copy_address(a, &(v->STR)); pushAddress(L,a); }',
'address*' => '{ Address a = (Address)g_malloc(sizeof(address)); copy_address(a, v->STR); pushAddress(L,a); }',
'int' => 'lua_pushnumber(L,(lua_Number)v->STR);',
'nstime_t' => 'lua_pushnumber(L,(lua_Number)nstime_to_sec(&(v->STR)));',
'nstime_t*' => 'lua_pushnumber(L,(lua_Number)nstime_to_sec(v->STR));'
}};
my %comments = %{{
'gchar[]' => 'string',
'gchar*' => 'string',
'guint' => 'number',
'guint8' => 'number',
'guint16' => 'number',
'guint32' => 'number',
'gint' => 'number',
'gint8' => 'number',
'gint16' => 'number',
'gint32' => 'number',
'gboolean' => 'boolean',
'address' => 'Address',
'address*' => 'Address',
'int' => 'number',
'nstime_t' => 'number (seconds, since 1-1-1970 if absolute)',
'nstime_t*' => 'number (seconds, since 1-1-1970 if absolute)',
}};
my %functs = ();
my %enums = ();
sub dotap {
my ($tname,$fname,$sname,@enums) = @_;
my $buf = '';
open FILE, "< $fname";
while(<FILE>) {
$buf .= $_;
}
close FILE;
$buf =~ s@/\*.*?\*/@@;
for my $ename (@enums) {
$enums{$ename} = [];
my $a = $enums{$ename};
my $enumre = "typedef\\s+enum[^{]*{([^}]*)}[\\s\\n]*" . ${ename} . "[\\s\\n]*;";
if ($buf =~ s/$enumre//ms ) {
$types{$ename} = "lua_pushnumber(L,(lua_Number)v->STR); /* $ename */";
my $ebody = $1;
$ebody =~ s/\s+//msg;
$comments{$ename} = "$ename: { $ebody }";
$comments{$ename} =~ s/,/|/g;
for (split /,/, $ebody) {
push @{$a}, $_;
}
}
}
my $re = "typedef\\s+struct.*?{([^}]*)}[\\s\\n]*($sname)[\\s\\n]*;";
my $body;
while ($buf =~ s/$re//ms) {
$body = $1;
}
die "could not find typedef $sname in $fname" if not defined $body and $sname ne "void";
my %elems = ();
while($body =~ s/\s*(.*?)([\w\d_]+)\s*\[\s*\d+\s*\]\s*;//) {
my ($k,$v) = ($2,$1 . "[]");
$v =~ s/const //g;
$v =~ s/\s+//g;
$elems{$k} = $v;
}
while($body =~ s/\s*(.*?)([\w\d_]+)\s*;//) {
my ($k,$v) = ($2,$1);
$v =~ s/const //g;
$v =~ s/\s+//g;
$elems{$k} = $v;
}
my $code = "static void wslua_${tname}_to_table(lua_State* L, const void* p) {\n\tconst $sname* v;\n\n\tv = (const $sname*)p;\n\tlua_newtable(L);\n\n";
my $doc = "Tap: $tname\n";
for my $n (sort keys %elems) {
my $fmt = $types{$elems{$n}};
my $lua_type;
if ($fmt) {
$code .= "\tlua_pushstring(L,\"$n\");\n\t";
($lua_type = $fmt) =~ s/\bSTR\b/$n/g;
$code .= $lua_type;
$code .= "\n\tlua_settable(L,-3);\n";
$doc .= "\t$n: $comments{$elems{$n}}\n";
}
}
$code .= "}\n\n";
$doc .= "\n";
$functs{$tname} = "wslua_${tname}_to_table";
return ($code,$doc);
}
open TAPSFILE, "< $ARGV[0]";
open CFILE, "> $ARGV[1]";
open DOCFILE, "> $ARGV[2]";
my $srcdir = $ARGV[3];
print CFILE <<"HEADER";
/* This file is autogenerated from ./taps by ./make-taps.pl */
/* DO NOT EDIT! */
#include "config.h"
#include "wslua.h"
#include <wsutil/nstime.h>
HEADER
print DOCFILE "\n";
while (<TAPSFILE>) {
s@#.*@@;
next if /^\s*$/;
my ($tname,$fname,$sname,@enums) = split /\s+/;
my ($c,$doc) = dotap($tname,$srcdir . "/" . $fname,$sname,@enums);
print CFILE "#include \"$fname\"\n";
print CFILE $c;
print DOCFILE $doc;
}
print CFILE <<"TBLHDR";
static tappable_t tappables[] = {
TBLHDR
for my $tname (sort keys %functs) {
print CFILE <<"TBLELEM";
{"$tname", $functs{$tname} },
TBLELEM
}
print CFILE <<"TBLFTR";
{"frame",NULL},
{NULL,NULL}
};
int wslua_set_tap_enums(lua_State* L) {
TBLFTR
for my $ename (sort keys %enums) {
print CFILE "\n\t/*\n\t * $ename\n\t */\n\tlua_newtable(L);\n";
for my $a (@{$enums{$ename}}) {
print CFILE <<"ENUMELEM";
lua_pushnumber(L,(lua_Number)$a);
lua_setglobal(L,"$a");
lua_pushnumber(L,(lua_Number)$a);
lua_pushstring(L,"$a");
lua_settable(L,-3);
ENUMELEM
}
print CFILE "\tlua_setglobal(L,\"$ename\");\n";
}
print CFILE <<"TAIL";
return 0;
}
tap_extractor_t wslua_get_tap_extractor(const gchar* name) {
tappable_t* t;
for(t = tappables; t->name; t++ ) {
if (g_str_equal(t->name,name)) return t->extractor;
}
return NULL;
}
TAIL
exit 0;