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 appropriate HTML documentation from them. This includes using the C-comments
after the macros for the API document info. 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 '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 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 write your own registration functions to get your new functions/classes into
Lua tables. (you can do so, but it's not advisable) 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. 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 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 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. Function and method names must be lower_underscore_case, no numbers.
Constants/enums must be ALLCAPS, and can have 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 auto-generate stuff use regex patterns that require the naming syntax to be
followed. followed.
@ -153,7 +153,7 @@ instead of one (for instance, ClassName__tostring).
Once you've created the appropriate array tables, define a registration Once you've created the appropriate array tables, define a registration
function named 'ClassName_register', where 'ClassName'is your class name, the 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 your file for WSLUA_CLASS_DEFINE, and it generates a register_wslua.c which
will call your ClassName_register function during Wireshark initialization. will call your ClassName_register function during Wireshark initialization.
Define a wslua_class structure which describes the class and register this in 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 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 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 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 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 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 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/declare_wslua.h
${CMAKE_BINARY_DIR}/epan/wslua/register_wslua.c ${CMAKE_BINARY_DIR}/epan/wslua/register_wslua.c
COMMAND COMMAND
${PERL_EXECUTABLE} ${PYTHON_EXECUTABLE}
${CMAKE_SOURCE_DIR}/epan/wslua/make-reg.pl ${CMAKE_SOURCE_DIR}/epan/wslua/make-reg.py
${WSLUA_MODULES} ${WSLUA_MODULES}
WORKING_DIRECTORY WORKING_DIRECTORY
${CMAKE_BINARY_DIR}/epan/wslua ${CMAKE_BINARY_DIR}/epan/wslua
DEPENDS DEPENDS
${CMAKE_SOURCE_DIR}/epan/wslua/make-reg.pl ${CMAKE_SOURCE_DIR}/epan/wslua/make-reg.py
${WSLUA_MODULES} ${WSLUA_MODULES}
# ${CMAKE_CURRENT_BINARY_DIR}/taps_wslua.c # ${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 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... the following macro would generate; but it does need to be registered and such, so...
WSLUA_CLASS_DEFINE_BASE(Struct,NOP,0); WSLUA_CLASS_DEFINE_BASE(Struct,NOP,0);