summaryrefslogtreecommitdiffstats
path: root/epan/wslua/make-taps.py
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-10 20:34:10 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-10 20:34:10 +0000
commite4ba6dbc3f1e76890b22773807ea37fe8fa2b1bc (patch)
tree68cb5ef9081156392f1dd62a00c6ccc1451b93df /epan/wslua/make-taps.py
parentInitial commit. (diff)
downloadwireshark-e4ba6dbc3f1e76890b22773807ea37fe8fa2b1bc.tar.xz
wireshark-e4ba6dbc3f1e76890b22773807ea37fe8fa2b1bc.zip
Adding upstream version 4.2.2.upstream/4.2.2
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'epan/wslua/make-taps.py')
-rwxr-xr-xepan/wslua/make-taps.py215
1 files changed, 215 insertions, 0 deletions
diff --git a/epan/wslua/make-taps.py b/epan/wslua/make-taps.py
new file mode 100755
index 0000000..14c5a39
--- /dev/null
+++ b/epan/wslua/make-taps.py
@@ -0,0 +1,215 @@
+#!/usr/bin/env python3
+#
+# make-taps.py
+#
+# By Gerald Combs <gerald@wireshark.org>
+# Based on make-taps.pl by Luis E. Garcia Onatnon <luis.ontanon@gmail.com>
+#
+# Wireshark - Network traffic analyzer
+# By Gerald Combs <gerald@wireshark.org>
+# Copyright 1998 Gerald Combs
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+'''\
+Extract structs from C headers to generate a function that pushes a lua table
+into the stack containing the elements of the struct.
+'''
+
+import argparse
+import configparser
+import os
+import re
+import sys
+
+
+this_dir = os.path.dirname(__file__)
+
+
+def get_tap_info(tap_name, header_file, struct_name, enum_types):
+ code = f'#include "{header_file}"\n'
+ doc = f'Tap: {tap_name}\n'
+ enums = {}
+ buf = ''
+
+ 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));',
+ }
+
+ 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)',
+ }
+
+ with open(os.path.join(this_dir, header_file), encoding='utf-8') as header_f:
+ for line in header_f:
+ # Remove comments
+ line = re.sub(r'\/\*.*?\*/', '', line)
+ line = re.sub(r'//.*', '', line)
+ buf += line
+
+ for enum in enum_types:
+ m = re.search(fr'typedef\s+enum[^{{]*{{([^}}]*)}}[\s\n]*{enum}[\s\n]*;', buf, flags=re.DOTALL)
+ if m:
+ types[enum] = f'lua_pushnumber(L,(lua_Number)v->STR); /* {enum} */'
+ econsts = m.group(1).splitlines()
+ econsts = [re.sub(r'\s+', '', item) for item in econsts]
+ econsts = [re.sub(',', '', item) for item in econsts]
+ econsts = [item for item in econsts if item]
+ enums[enum] = econsts
+ ebody = '|'.join(econsts)
+ comments[enum] = f'{enum}: {{ {ebody} }}'
+
+ m = re.search(fr'typedef\s+struct.*?{{([^}}]*)}}[\s\n]*({struct_name})[\s\n]*;', buf, flags=re.DOTALL)
+ if not m:
+ sys.stderr.write(f'could not find typedef {struct_name} in {header_file}')
+ sys.exit(1)
+
+ body = m.group(1)
+
+ elems = {}
+
+ for line in body.splitlines():
+ k = None
+ v = None
+
+ m = re.search(r'\s*(.*?)([\w\d_]+)\s*\[\s*\d+\s*\]\s*;', line)
+ if m:
+ k = m.group(2)
+ v = m.group(1)
+ v += '[]'
+
+ m = re.search(r'\s*(.*?)([\w\d_]+)\s*;', line)
+ if m:
+ k = m.group(2)
+ v = m.group(1)
+
+ if v and k:
+ v = re.sub(r'const ', '', v)
+ v = re.sub(r'\s+', '', v)
+ elems[k] = v
+
+ code += f'static void wslua_{tap_name}_to_table(lua_State* L, const void* p) {{\n\tconst {struct_name}* v;\n\n\tv = (const {struct_name}*)p;\n\tlua_newtable(L);\n\n'
+
+ for el in sorted(elems):
+ try:
+ fmt = types[elems[el]]
+ code += f'\tlua_pushstring(L,\"{el}\");\n\t'
+ lua_type = re.sub(r'\bSTR\b', el, fmt)
+ code += lua_type
+ code += '\n\tlua_settable(L,-3);\n'
+ doc += f'\t{el}: {comments[elems[el]]}\n'
+ except KeyError:
+ pass
+
+ code += "}\n\n"
+ doc += "\n"
+
+ return (code, doc, enums)
+
+
+def main():
+ parser = argparse.ArgumentParser(description="Generate bindings required for Lua taps.")
+ parser.add_argument("out_c", metavar='C file', help="output C file")
+ parser.add_argument("out_doc", metavar='documentation file', help="output text file")
+ args = parser.parse_args()
+
+ tap_config = configparser.ConfigParser()
+ tap_config.read(os.path.join(this_dir, 'taps.ini'))
+
+ enums = {}
+ c_body = '''\
+/* This file is autogenerated from ./taps by ./make-taps.py */
+/* DO NOT EDIT! */
+
+#include "config.h"
+
+#include "wslua.h"
+
+#include <wsutil/nstime.h>
+
+'''
+ doc_body = '\n'
+
+ for tap_name in tap_config.sections():
+ tap_d = tap_config[tap_name]
+ enum_types = []
+ if 'enum_types' in tap_d.keys():
+ enum_types = tap_d['enum_types'].split(' ')
+ (code, doc, file_enums) = get_tap_info(tap_name, tap_d['header_file'], tap_d['struct_name'], enum_types)
+ c_body += code
+ doc_body += doc
+ enums.update(file_enums)
+
+ c_body += 'static tappable_t tappables[] = {\n'
+ for tap_name in sorted(tap_config.sections()):
+ c_body += f'\t{{"{tap_name}", wslua_{tap_name}_to_table }},\n'
+ c_body += '''\
+ {"frame",NULL},
+ {NULL,NULL}
+};
+'''
+
+ c_body += '\nint wslua_set_tap_enums(lua_State* L) {\n'
+ for enum in sorted(enums):
+ c_body += f'\n\t/*\n\t * {enum}\n\t */\n\tlua_newtable(L);\n'
+ for econst in enums[enum]:
+ c_body += f'''\
+ lua_pushnumber(L,(lua_Number){econst});
+ lua_setglobal(L,"{econst}");
+ lua_pushnumber(L,(lua_Number){econst});
+ lua_pushstring(L,"{econst}");
+ lua_settable(L,-3);
+'''
+ c_body += f'\tlua_setglobal(L,\"{enum}\");\n'
+ c_body += '\treturn 0;\n}\n'
+
+ c_body += '''\
+
+
+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;
+}
+'''
+
+ with open(args.out_c, mode='w', encoding='utf-8') as out_c_f:
+ out_c_f.write(c_body)
+
+ with open(args.out_doc, mode='w', encoding='utf-8') as out_doc_f:
+ out_doc_f.write(doc_body)
+
+if __name__ == '__main__':
+ main()