wslua: Port epan/wslua/make-reg.py to Python3

Port the script that creates
declare_wslua.h and register_wslua.c
to Python3.
Ping #18152.
This commit is contained in:
Moshe Kaplan 2022-06-23 22:24:59 -04:00 committed by Moshe Kaplan
parent acb8158033
commit 26f87b3250
5 changed files with 122 additions and 110 deletions

View File

@ -34,14 +34,14 @@ wsluarm.pl', which searches C-files for the known macros and generates
appropriate HTML documentation from them. This includes using the C-comments
after the macros for the API document info.
Likewise, another Perl script called 'make-reg.pl' generates the C-files
Likewise, another script called 'make-reg.py' generates the C-files
'register_wslua.c' and 'declare_wslua.h', based on the C-macros it searches
for in existing source files. The code this Perl script auto-generates is
for in existing source files. The code this script auto-generates is
what actually registers some classes/functions into Lua - you don't have to
write your own registration functions to get your new functions/classes into
Lua tables. (you can do so, but it's not advisable)
Both of the perl scripts above are given the C-source files to search through
Both of the scripts above are given the C-source files to search through
by the make process, generated from the lists in epan/wslua/CMakeLists.txt.
Naturally if you add new source files, you need to add them to the list in
epan/wslua/CMakeLists.txt. You also have to add the module name into
@ -72,7 +72,7 @@ Class/object names must be UpperCamelCase, no numbers/underscores.
Function and method names must be lower_underscore_case, no numbers.
Constants/enums must be ALLCAPS, and can have numbers.
The above rules are more than merely conventions - the Perl scripts which
The above rules are more than merely conventions - the scripts which
auto-generate stuff use regex patterns that require the naming syntax to be
followed.
@ -153,7 +153,7 @@ instead of one (for instance, ClassName__tostring).
Once you've created the appropriate array tables, define a registration
function named 'ClassName_register', where 'ClassName'is your class name, the
same one used in WSLUA_CLASS_DEFINE. The make-reg.pl Perl script will search
same one used in WSLUA_CLASS_DEFINE. The make-reg.py script will search
your file for WSLUA_CLASS_DEFINE, and it generates a register_wslua.c which
will call your ClassName_register function during Wireshark initialization.
Define a wslua_class structure which describes the class and register this in
@ -365,7 +365,7 @@ Example:
WSLUA_CONSTRUCTOR - this is used to define a function of a class that is a
static function rather than a per-object method; i.e., from a Lua perspective
the function is called as 'myObj.func()' instead of 'myObj:func()'. From a
C-code perspective the code generated by make-reg.pl does not treat this
C-code perspective the code generated by make-reg.py does not treat this
differently than a WSLUA_METHOD, the only real difference being that the code
you write within the function won't be checking the object instance as the
first passed-in argument on the Lua-API stack. But from a documentation

View File

@ -92,13 +92,13 @@ add_custom_command(
${CMAKE_BINARY_DIR}/epan/wslua/declare_wslua.h
${CMAKE_BINARY_DIR}/epan/wslua/register_wslua.c
COMMAND
${PERL_EXECUTABLE}
${CMAKE_SOURCE_DIR}/epan/wslua/make-reg.pl
${PYTHON_EXECUTABLE}
${CMAKE_SOURCE_DIR}/epan/wslua/make-reg.py
${WSLUA_MODULES}
WORKING_DIRECTORY
${CMAKE_BINARY_DIR}/epan/wslua
DEPENDS
${CMAKE_SOURCE_DIR}/epan/wslua/make-reg.pl
${CMAKE_SOURCE_DIR}/epan/wslua/make-reg.py
${WSLUA_MODULES}
# ${CMAKE_CURRENT_BINARY_DIR}/taps_wslua.c
)

View File

@ -1,100 +0,0 @@
#!/usr/bin/perl
#
# make-reg.pl
# Registration Macros Generator
#
# (c) 2006, 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
use strict;
use Getopt::Long;
my @classes = ();
my @functions = ();
my @internal_functions = ();
my $source_dir = "";
GetOptions('dir=s' => \$source_dir);
my $filename;
while ($filename = $ARGV[0]) {
shift;
if ($source_dir and ! -e $filename) {
$filename = $source_dir . '/' . $filename;
}
open FILE, $filename or warn "Couldn't open file $filename: $!";
while (<FILE>) {
push @classes, $1 if /WSLUA_CLASS_DEFINE(?:_BASE)?\050\s*([A-Za-z0-9]+)/;
push @functions, $1 if /WSLUA_FUNCTION\s+wslua_([a-z_0-9]+)/;
push @internal_functions, $1 if /WSLUA_INTERNAL_FUNCTION\s+wslua_([a-z_0-9]+)/;
}
}
open C, ">register_wslua.c";
open H, ">declare_wslua.h";
print H "/* This file is automatically generated by make-reg.pl; do not edit! */\n\n";
print C "/* This file is automatically generated by make-reg.pl; do not edit! */\n\n";
print H "#define WSLUA_DECLARE_CLASSES() \\\n";
for (@classes) {
print H "\tWSLUA_CLASS_DECLARE($_);\\\n"
}
print H "\n\n";
print H "#define WSLUA_DECLARE_FUNCTIONS() \\\n";
for (@functions) {
print H "\tWSLUA_FUNCTION wslua_$_(lua_State* L);\\\n"
}
for (@internal_functions) {
print H "\tWSLUA_INTERNAL_FUNCTION wslua_$_(lua_State* L);\\\n"
}
print H "\n\n";
print H "extern void wslua_register_classes(lua_State* L);\n";
print H "extern void wslua_register_functions(lua_State* L);\n";
print H "\n\n";
print C '#include "config.h"' . "\n";
print C '#include "wslua.h"' . "\n\n";
print C '#include "lua_bitop.h"' . "\n\n";
print C "static void wslua_reg_module(lua_State* L, const char *name _U_, lua_CFunction func) { \n";
print C "\tlua_pushcfunction(L, func);\n";
# why was this done? this string was never used for anything - I'll keep the argument "name" above
# just in case this needs to be reverted someday, but I think this thing's from old code or something
# print C "\tlua_pushstring(L, name);\n";
# print C "\tlua_call(L, 1, 0);\n";
print C "\tlua_call(L, 0, 0);\n";
print C "}\n\n";
print C "void wslua_register_classes(lua_State* L) { \n";
for (@classes) {
print C "\twslua_reg_module(L, \"${_}\", ${_}_register);\n";
}
print C "\twslua_reg_module(L, \"bit\", luaopen_bit);\n";
#print C "\twslua_reg_module(L, \"rex_pcre2\", luaopen_rex_pcre2);\n";
print C "\tlua_pushcfunction(L, luaopen_rex_pcre2);\n";
print C "\tlua_call(L, 0, 1);\n";
print C "\tlua_setglobal(L, \"rex_pcre2\");\n";
print C "}\n\n";
print C "void wslua_register_functions(lua_State* L) {\n";
for (@functions) {
print C "\tWSLUA_REGISTER_FUNCTION($_); \n"
}
for (@internal_functions) {
print C "\tWSLUA_REGISTER_FUNCTION($_); \n"
}
print C "}\n\n";
close H;
close C;

112
epan/wslua/make-reg.py Normal file
View File

@ -0,0 +1,112 @@
#!/usr/bin/env python
#
# make-reg.py
# Registration Macros Generator
#
# Copyright 2022 by Moshe Kaplan
# Based on make-reg.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
import argparse
import re
def parse_file(file_content):
# extract classes, functions, and internal functions
# and return them as a tuple
CLASS_PATTERN = r'WSLUA_CLASS_DEFINE(?:_BASE)?\050\s*([A-Za-z0-9]+)'
FUNCTION_PATTERN = r'WSLUA_FUNCTION\s+wslua_([a-z_0-9]+)'
INTERNAL_FUNCTION_PATTERN = r'WSLUA_INTERNAL_FUNCTION\s+wslua_([a-z_0-9]+)'
class_matches = re.findall(CLASS_PATTERN, file_content)
function_matches = re.findall(FUNCTION_PATTERN, file_content)
internal_function_matches = re.findall(INTERNAL_FUNCTION_PATTERN, file_content)
return class_matches, function_matches, internal_function_matches
def generate_declare_wslua_h(classes, functions, internal_functions):
output_lines = []
output_lines += ["/* This file is automatically generated by make-reg.py; do not edit! */\n"]
output_lines += ["#define WSLUA_DECLARE_CLASSES() \\"]
for lua_class in classes:
output_lines += ["\tWSLUA_CLASS_DECLARE({lua_class});\\".format(lua_class=lua_class)]
output_lines += ["\n"]
output_lines += ["#define WSLUA_DECLARE_FUNCTIONS() \\"]
for lua_function in functions:
output_lines += ["\tWSLUA_FUNCTION wslua_{lua_function}(lua_State* L);\\".format(lua_function=lua_function)]
for lua_internal_function in internal_functions:
output_lines += ["\tWSLUA_INTERNAL_FUNCTION wslua_{lua_internal_function}(lua_State* L);\\".format(lua_internal_function=lua_internal_function)]
output_lines += ["\n"]
output_lines += ["extern void wslua_register_classes(lua_State* L);"]
output_lines += ["extern void wslua_register_functions(lua_State* L);"]
output_lines += ["\n\n"]
return "\n".join(output_lines)
def generate_register_wslua_c(classes, functions, internal_functions):
output_lines = []
output_lines += ["/* This file is automatically generated by make-reg.py; do not edit! */\n"]
output_lines += ['#include "config.h"']
output_lines += ['#include "wslua.h"\n']
output_lines += ['#include "lua_bitop.h"\n']
output_lines += ["static void wslua_reg_module(lua_State* L, const char *name _U_, lua_CFunction func) {"]
output_lines += ["\tlua_pushcfunction(L, func);"]
output_lines += ["\tlua_call(L, 0, 0);"]
output_lines += ["}\n"]
output_lines += ["void wslua_register_classes(lua_State* L) {"]
for lua_class in classes:
output_lines += ["\twslua_reg_module(L, \"{lua_class}\", {lua_class}_register);".format(lua_class=lua_class)]
output_lines += ["\twslua_reg_module(L, \"bit\", luaopen_bit);"]
output_lines += ["\tlua_pushcfunction(L, luaopen_rex_pcre2);"]
output_lines += ["\tlua_call(L, 0, 1);"]
output_lines += ["\tlua_setglobal(L, \"rex_pcre2\");"]
output_lines += ["}\n"]
output_lines += ["void wslua_register_functions(lua_State* L) {"]
for lua_function in functions:
output_lines += ["\tWSLUA_REGISTER_FUNCTION({lua_function});".format(lua_function=lua_function)]
for lua_internal_function in internal_functions:
output_lines += ["\tWSLUA_REGISTER_FUNCTION({lua_internal_function});".format(lua_internal_function=lua_internal_function)]
output_lines += ["}\n"]
return "\n".join(output_lines)
def main():
parser = argparse.ArgumentParser(description="Generate the registration macros for Lua code.")
parser.add_argument("files", metavar='files', nargs='+', help="paths to Lua C code")
parsed_args = parser.parse_args()
lua_classes = []
lua_functions = []
lua_internal_functions = []
for filename in parsed_args.files:
with open(filename) as fh:
class_matches, function_matches, internal_function_matches = parse_file(fh.read())
lua_classes += class_matches
lua_functions += function_matches
lua_internal_functions += internal_function_matches
declare_wslua_h_content = generate_declare_wslua_h(lua_classes, lua_functions, lua_internal_functions)
register_wslua_c_content = generate_register_wslua_c(lua_classes, lua_functions, lua_internal_functions)
with open('register_wslua.c', 'w') as fh:
fh.write(register_wslua_c_content)
with open('declare_wslua.h', 'w') as fh:
fh.write(declare_wslua_h_content)
if __name__ == '__main__':
main()

View File

@ -145,7 +145,7 @@
*/
/* The following line is here so that make-reg.pl does the right thing. This 'Struct' class
/* The following line is here so that make-reg.py does the right thing. This 'Struct' class
isn't really a class, so it doesn't have the checkStruct/pushStruct/etc. functions
the following macro would generate; but it does need to be registered and such, so...
WSLUA_CLASS_DEFINE_BASE(Struct,NOP,0);