HACK: pinfo->private_data points to smb_info again
[wireshark-wip.git] / epan / wslua / make-taps.pl
blob81e5f40004f4d3b66b1d5061522a931af693f7d5
1 #!/usr/bin/perl
3 # make-taps.pl
4 # Extract structs from C headers to generate a function that
5 # pushes a lua table into the stack containing the elements of
6 # the struct.
8 # (c) 2006 Luis E. Garcia Ontanon <luis@ontanon.org>
10 # $Id$
12 # Wireshark - Network traffic analyzer
13 # By Gerald Combs <gerald@wireshark.org>
14 # Copyright 2006 Gerald Combs
16 # This program is free software; you can redistribute it and/or
17 # modify it under the terms of the GNU General Public License
18 # as published by the Free Software Foundation; either version 2
19 # of the License, or (at your option) any later version.
21 # This program is distributed in the hope that it will be useful,
22 # but WITHOUT ANY WARRANTY; without even the implied warranty of
23 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 # GNU General Public License for more details.
26 # You should have received a copy of the GNU General Public License
27 # along with this program; if not, write to the Free Software
28 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
30 use strict;
32 my %types = %{{
33 'gchar[]' => 'lua_pushstring(L,(char*)v->%s);',
34 'gchar*' => 'lua_pushstring(L,(char*)v->%s);',
35 'guint' => 'lua_pushnumber(L,(lua_Number)v->%s);',
36 'guint8' => 'lua_pushnumber(L,(lua_Number)v->%s);',
37 'guint16' => 'lua_pushnumber(L,(lua_Number)v->%s);',
38 'guint32' => 'lua_pushnumber(L,(lua_Number)v->%s);',
39 'gint' => 'lua_pushnumber(L,(lua_Number)v->%s);',
40 'gint8' => 'lua_pushnumber(L,(lua_Number)v->%s);',
41 'gint16' => 'lua_pushnumber(L,(lua_Number)v->%s);',
42 'gint32' => 'lua_pushnumber(L,(lua_Number)v->%s);',
43 'gboolean' => 'lua_pushboolean(L,(int)v->%s);',
44 'address' => '{ Address a = (Address)g_malloc(sizeof(address)); COPY_ADDRESS(a, &(v->%s)); pushAddress(L,a); }',
45 'address*' => '{ Address a = (Address)g_malloc(sizeof(address)); COPY_ADDRESS(a, v->%s); pushAddress(L,a); }',
46 'int' => 'lua_pushnumber(L,(lua_Number)v->%s);',
47 'nstime_t' => '{lua_Number t = (lua_Number) v->%s.secs; t += v->%s.nsecs * 1e-9; lua_pushnumber(L,t); }',
48 'nstime_t*' => '{lua_Number t = (lua_Number) v->%s->secs; t += v->%s->nsecs * 1e-9; lua_pushnumber(L,t); }',
49 }};
51 my %comments = %{{
52 'gchar[]' => 'string',
53 'gchar*' => 'string',
54 'guint' => 'number',
55 'guint8' => 'number',
56 'guint16' => 'number',
57 'guint32' => 'number',
58 'gint' => 'number',
59 'gint8' => 'number',
60 'gint16' => 'number',
61 'gint32' => 'number',
62 'gboolean' => 'boolean',
63 'address' => 'Address',
64 'address*' => 'Address',
65 'int' => 'number',
66 'nstime_t' => 'number (seconds, since 1-1-1970 if absolute)',
67 'nstime_t*' => 'number (seconds, since 1-1-1970 if absolute)',
68 }};
71 my %functs = ();
73 my %enums = ();
75 sub dotap {
76 my ($tname,$fname,$sname,@enums) = @_;
77 my $buf = '';
79 open FILE, "< $fname";
80 while(<FILE>) {
81 $buf .= $_;
83 close FILE;
85 $buf =~ s@/\*.*?\*/@@;
87 for my $ename (@enums) {
88 $enums{$ename} = [];
89 my $a = $enums{$ename};
91 my $enumre = "typedef\\s+enum[^{]*{([^}]*)}[\\s\\n]*" . ${ename} . "[\\s\\n]*;";
92 if ($buf =~ s/$enumre//ms ) {
93 $types{$ename} = "/*$ename*/ lua_pushnumber(L,(lua_Number)v->%s);";
94 my $ebody = $1;
95 $ebody =~ s/\s+//msg;
96 $comments{$ename} = "$ename: { $ebody }";
97 $comments{$ename} =~ s/,/|/g;
98 for (split /,/, $ebody) {
99 push @{$a}, $_;
104 my $re = "typedef\\s+struct.*?{([^}]*)}[\\s\\n]*($sname)[\\s\\n]*;";
105 my $body;
107 while ($buf =~ s/$re//ms) {
108 $body = $1;
111 die "could not find typedef $sname in $fname" if not defined $body and $sname ne "void";
113 my %elems = ();
115 while($body =~ s/\s*(.*?)([\w\d_]+)\s*\[\s*\d+\s*\]\s*;//) {
116 my ($k,$v) = ($2,$1 . "[]");
117 $v =~ s/\s+//g;
118 $elems{$k} = $v;
121 while($body =~ s/\s*(.*?)([\w\d_]+)\s*;//) {
122 my ($k,$v) = ($2,$1);
123 $v =~ s/\s+//g;
124 $elems{$k} = $v;
127 my $code = "static void wslua_${tname}_to_table(lua_State* L, const void* p) { $sname* v _U_; v = ($sname*)p; lua_newtable(L);\n";
128 my $doc = "Tap: $tname\n";
130 for my $n (sort keys %elems) {
131 my $fmt = $types{$elems{$n}};
133 if ($fmt) {
134 $code .= "\tlua_pushstring(L,\"$n\"); ";
135 $code .= sprintf($fmt,$n,$n) . " lua_settable(L,-3);\n";
136 $doc .= "\t$n: $comments{$elems{$n}}\n";
141 $code .= "}\n\n";
142 $doc .= "\n";
144 $functs{$tname} = "wslua_${tname}_to_table";
146 return ($code,$doc);
150 open TAPSFILE, "< $ARGV[0]";
151 open CFILE, "> $ARGV[1]";
152 open DOCFILE, "> $ARGV[2]";
154 print CFILE <<"HEADER";
155 /* This file is autogenerated from ./taps by ./make-taps.pl */
156 /* DO NOT EDIT! */
158 #include "config.h"
160 #include "wslua.h"
162 HEADER
164 print DOCFILE "\n";
166 while (<TAPSFILE>) {
167 s@#.*@@;
168 next if /^\s*$/;
169 my ($tname,$fname,$sname,@enums) = split /\s+/;
170 my ($c,$doc) = dotap($tname,$fname,$sname,@enums);
171 print CFILE "#include \"$fname\"\n";
172 print CFILE $c;
173 print DOCFILE $doc;
176 print CFILE <<"TBLHDR";
177 static tappable_t tappables[] = {
178 TBLHDR
180 for my $tname (sort keys %functs) {
181 print CFILE <<"TBLELEM";
182 {"$tname", $functs{$tname} },
183 TBLELEM
186 print CFILE <<"TBLFTR";
187 {"frame",NULL},
188 {NULL,NULL}
191 int wslua_set_tap_enums(lua_State* L _U_) {
192 TBLFTR
195 for my $ename (sort keys %enums) {
196 print CFILE "\n\t/*\n\t * $ename\n\t */\n\tlua_newtable(L);\n";
197 for my $a (@{$enums{$ename}}) {
198 print CFILE <<"ENUMELEM";
199 lua_pushnumber(L,(lua_Number)$a); lua_setglobal(L,"$a");
200 lua_pushnumber(L,(lua_Number)$a); lua_pushstring(L,"$a"); lua_settable(L,-3);
201 ENUMELEM
203 print CFILE "\tlua_setglobal(L,\"$ename\");\n";
206 print CFILE <<"TAIL";
207 return 0;
211 tap_extractor_t wslua_get_tap_extractor(const gchar* name) {
212 tappable_t* t;
213 for(t = tappables; t->name; t++ ) {
214 if (g_str_equal(t->name,name)) return t->extractor;
217 return NULL;
220 TAIL
221 exit 0;