forked from osmocom/wireshark
Rewrite make-dissector-reg.py in C
The output compares equal to make-dissector-reg.py and the regex should be more robust (multiline, complete start of function definition). The primary motivation is to clean up the python script. This small binary results in much cleaner code. The python script is used only to generate plugin code, therefore it is renamed. Also in my casual measurements the C code is much faster (without cache) than the python script with the cache. Change-Id: Id4e8cac3c836d56775aba4819357a95ef19bcb85 Reviewed-on: https://code.wireshark.org/review/24497 Petri-Dish: Anders Broman <a.broman58@gmail.com> Tested-by: Petri Dish Buildbot Reviewed-by: Anders Broman <a.broman58@gmail.com>pespin/amr
parent
129cb60f56
commit
fe0c2b0485
|
@ -32,8 +32,8 @@ epan/dissectors/dcerpc/*/packet-dcerpc-*.[hc]
|
|||
epan/dissectors/mesa
|
||||
epan/dissectors/xcbproto
|
||||
epan/dissectors/packet-ncp2222.c
|
||||
epan/dissectors/dissectors-cache.pkl
|
||||
epan/dissectors/dissectors.c
|
||||
epan/dissectors/make-dissectors
|
||||
epan/dtd_parse.c
|
||||
epan/dtd_preparse.c
|
||||
epan/packet-ncp2222.c
|
||||
|
|
|
@ -1,32 +1,21 @@
|
|||
#
|
||||
MACRO(REGISTER_DISSECTOR_FILES _outputfile _registertype )
|
||||
include(LocatePythonModule)
|
||||
locate_python_module(make-dissector-reg REQUIRED PATHS ${CMAKE_SOURCE_DIR}/tools)
|
||||
locate_python_module(make-plugin-reg REQUIRED PATHS ${CMAKE_SOURCE_DIR}/tools)
|
||||
|
||||
if(${_registertype} STREQUAL "dissectors" )
|
||||
set( _makeregistertype "dissectorsinfile" )
|
||||
set( _ftmp "${CMAKE_CURRENT_BINARY_DIR}/_regc.tmp" )
|
||||
set( _depends ${ARGN} )
|
||||
file(REMOVE ${_ftmp})
|
||||
foreach(f ${_depends})
|
||||
file(APPEND ${_ftmp} "${f}\n")
|
||||
endforeach()
|
||||
set( _sources ${_ftmp} )
|
||||
else()
|
||||
set( _makeregistertype ${_registertype} )
|
||||
set( _sources ${ARGN} )
|
||||
set( _depends ${_sources} )
|
||||
endif()
|
||||
set( _makeregistertype ${_registertype} )
|
||||
set( _sources ${ARGN} )
|
||||
set( _depends ${_sources} )
|
||||
ADD_CUSTOM_COMMAND(
|
||||
OUTPUT
|
||||
${_outputfile}
|
||||
COMMAND ${PYTHON_EXECUTABLE}
|
||||
${PY_MAKE-DISSECTOR-REG}
|
||||
${PY_MAKE-PLUGIN-REG}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}
|
||||
${_makeregistertype}
|
||||
${_sources}
|
||||
DEPENDS
|
||||
${_depends}
|
||||
${PY_MAKE-DISSECTOR-REG}
|
||||
${PY_MAKE-PLUGIN-REG}
|
||||
)
|
||||
ENDMACRO(REGISTER_DISSECTOR_FILES)
|
||||
|
|
|
@ -58,7 +58,7 @@ override_dh_install:
|
|||
|
||||
override_dh_fixperms:
|
||||
dh_fixperms
|
||||
chmod 644 debian/wireshark-dev/usr/share/pyshared/make-dissector-reg.py \
|
||||
chmod 644 debian/wireshark-dev/usr/share/pyshared/make-plugin-reg.py \
|
||||
debian/wireshark-dev/usr/share/pyshared/wireshark_be.py \
|
||||
debian/wireshark-dev/usr/share/pyshared/wireshark_gen.py
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
tools/idl2wrs usr/bin
|
||||
tools/idl2deb usr/bin
|
||||
tools/asn2deb usr/bin
|
||||
tools/make-dissector-reg.py usr/share/pyshared
|
||||
tools/make-plugin-reg.py usr/share/pyshared
|
||||
tools/wireshark_be.py usr/share/pyshared
|
||||
tools/wireshark_gen.py usr/share/pyshared
|
||||
tools/asn2wrs.py usr/share/pyshared
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1900,6 +1900,12 @@ subpkginclude_HEADERS = \
|
|||
noinst_HEADERS = \
|
||||
$(FILE_DISSECTOR_INCLUDES)
|
||||
|
||||
noinst_PROGRAMS = make-dissectors
|
||||
|
||||
make_dissectors_CFLAGS = $(WS_CPPFLAGS) $(GLIB_CFLAGS)
|
||||
|
||||
make_dissectors_LDADD = $(GLIB_LIBS)
|
||||
|
||||
# include asn1 in the source tarball. But nothing to build...
|
||||
DIST_SUBDIRS = asn1 dcerpc
|
||||
|
||||
|
@ -1929,31 +1935,13 @@ x11-dissector: $(top_srcdir)/tools/process-x11-fields.pl $(srcdir)/x11-fields $(
|
|||
# with the register routines for all protocols and a function pointer array
|
||||
# with the handoff registration routines for all protocols.
|
||||
#
|
||||
# We do this by scanning through sources. If that turns out to be too slow,
|
||||
# maybe we could just require every .o file to have an register routine
|
||||
# of a given name (packet-aarp.o -> proto_register_aarp, etc.).
|
||||
#
|
||||
# Formatting conventions: The name of the proto_register_* routines an
|
||||
# proto_reg_handoff_* routines must start in column zero, or must be
|
||||
# preceded only by "void " starting in column zero, and must not be
|
||||
# inside #if.
|
||||
#
|
||||
# ALL_DISSECTORS_SRC is assumed to have all the files that need to be scanned.
|
||||
#
|
||||
# We use a script to generate the dissectors.c file.
|
||||
# The first argument is the directory in which the source files live.
|
||||
# The second argument is "dissectors", to indicate that we should build
|
||||
# a dissectors.c file for libwireshark.
|
||||
# All subsequent arguments are the files to scan.
|
||||
#
|
||||
dissectors.c: $(ALL_DISSECTORS_SRC) Custom.common \
|
||||
$(top_srcdir)/tools/make-dissector-reg.py
|
||||
@echo Making dissectors.c ; \
|
||||
$(PYTHON) $(top_srcdir)/tools/make-dissector-reg.py $(srcdir) \
|
||||
dissectors $(ALL_DISSECTORS_SRC) ;
|
||||
|
||||
CLEANFILES = \
|
||||
dissectors-cache.pkl
|
||||
dissectors.c: make-dissectors $(ALL_DISSECTORS_SRC)
|
||||
@echo Making dissectors.c
|
||||
$(file >$@.in,$(filter %.c,$^))
|
||||
$(builddir)/make-dissectors @$@.in > $@
|
||||
@rm $@.in
|
||||
|
||||
DISTCLEANFILES = \
|
||||
$(NODIST_GENERATED_FILES)
|
||||
|
|
|
@ -27,9 +27,8 @@ typedef struct _dissector_reg {
|
|||
WS_DLL_PUBLIC dissector_reg_t dissector_reg_proto[];
|
||||
WS_DLL_PUBLIC dissector_reg_t dissector_reg_handoff[];
|
||||
|
||||
WS_DLL_PUBLIC gulong dissector_reg_proto_count(void);
|
||||
|
||||
WS_DLL_PUBLIC gulong dissector_reg_handoff_count(void);
|
||||
WS_DLL_PUBLIC const gulong dissector_reg_proto_count;
|
||||
WS_DLL_PUBLIC const gulong dissector_reg_handoff_count;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -0,0 +1,157 @@
|
|||
/* make-dissectors.c
|
||||
* Tool to build the dissector registration arrays.
|
||||
*
|
||||
* Wireshark - Network traffic analyzer
|
||||
* By Gerald Combs <gerald@wireshark.org>
|
||||
* Copyright 1998 Gerald Combs
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <glib.h>
|
||||
|
||||
#define ARRAY_RESERVED_SIZE 2048
|
||||
|
||||
GRegex *protos_regex, *handoffs_regex;
|
||||
|
||||
static int
|
||||
compare_symbols(gconstpointer a, gconstpointer b)
|
||||
{
|
||||
return g_strcmp0(*(const char **)a, *(const char **)b);
|
||||
}
|
||||
|
||||
static void
|
||||
scan_matches(GRegex *regex, const char *string, GPtrArray *dst)
|
||||
{
|
||||
GMatchInfo *match_info;
|
||||
char *match;
|
||||
|
||||
g_regex_match(regex, string, G_REGEX_MATCH_NOTEMPTY, &match_info);
|
||||
while (g_match_info_matches(match_info)) {
|
||||
match = g_match_info_fetch(match_info, 1);
|
||||
g_ptr_array_add(dst, match);
|
||||
g_match_info_next(match_info, NULL);
|
||||
}
|
||||
g_match_info_free(match_info);
|
||||
}
|
||||
|
||||
static void
|
||||
scan_file(const char *file, GPtrArray *protos, GPtrArray *handoffs)
|
||||
{
|
||||
char *contents;
|
||||
|
||||
if (!g_file_get_contents(file, &contents, NULL, NULL))
|
||||
return;
|
||||
scan_matches(protos_regex, contents, protos);
|
||||
scan_matches(handoffs_regex, contents, handoffs);
|
||||
g_free(contents);
|
||||
}
|
||||
|
||||
static void
|
||||
scan_list(const char *list, GPtrArray *protos, GPtrArray *handoffs)
|
||||
{
|
||||
char *contents, *arg;
|
||||
|
||||
if (!g_file_get_contents(list, &contents, NULL, NULL))
|
||||
return;
|
||||
for (arg = strtok(contents, " \n"); arg != NULL; arg = strtok(NULL, " \n")) {
|
||||
scan_file(arg, protos, handoffs);
|
||||
}
|
||||
g_free(contents);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
GPtrArray *protos = NULL, *handoffs = NULL;
|
||||
GError *err = NULL;
|
||||
guint i;
|
||||
|
||||
protos = g_ptr_array_new_full(ARRAY_RESERVED_SIZE, g_free);
|
||||
handoffs = g_ptr_array_new_full(ARRAY_RESERVED_SIZE, g_free);
|
||||
|
||||
protos_regex = g_regex_new("void\\s+(proto_register_[[:alnum:]_]+)\\s*\\(\\s*void\\s*\\)\\s*{",
|
||||
G_REGEX_OPTIMIZE, G_REGEX_MATCH_NOTEMPTY, &err);
|
||||
if (err) {
|
||||
fprintf(stderr, "GRegex: %s\n", err->message);
|
||||
exit(1);
|
||||
}
|
||||
handoffs_regex = g_regex_new("void\\s+(proto_reg_handoff_[[:alnum:]_]+)\\s*\\(\\s*void\\s*\\)\\s*{",
|
||||
G_REGEX_OPTIMIZE, G_REGEX_MATCH_NOTEMPTY, &err);
|
||||
if (err) {
|
||||
fprintf(stderr, "GRegex: %s\n", err->message);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
for (int arg = 1; arg < argc; arg++) {
|
||||
if (argv[arg][0] == '@') {
|
||||
scan_list(&argv[arg][1], protos, handoffs);
|
||||
}
|
||||
else {
|
||||
scan_file(argv[arg], protos, handoffs);
|
||||
}
|
||||
}
|
||||
|
||||
g_ptr_array_sort(protos, compare_symbols);
|
||||
g_ptr_array_sort(handoffs, compare_symbols);
|
||||
|
||||
printf("/*\n"
|
||||
" * Do not modify this file. Changes will be overwritten.\n"
|
||||
" *\n"
|
||||
" * Generated automatically by the \"dissectors.c\" target using\n"
|
||||
" * \"make-dissectors\".\n"
|
||||
" */\n"
|
||||
"\n"
|
||||
"#include <ws_symbol_export.h>\n"
|
||||
"#include <dissectors.h>\n"
|
||||
"\n");
|
||||
|
||||
printf("const gulong dissector_reg_proto_count = %d;\n"
|
||||
"const gulong dissector_reg_handoff_count = %d;\n"
|
||||
"\n",
|
||||
protos->len, handoffs->len);
|
||||
|
||||
for (i = 0; i < protos->len; i++) {
|
||||
printf("void %s(void);\n", (char *)protos->pdata[i]);
|
||||
}
|
||||
printf("\n"
|
||||
"dissector_reg_t dissector_reg_proto[] = {\n");
|
||||
for (i = 0; i < protos->len; i++) {
|
||||
printf(" { \"%s\", %s },\n", (char *)protos->pdata[i], (char *)protos->pdata[i]);
|
||||
}
|
||||
printf(" { NULL, NULL }\n"
|
||||
"};\n"
|
||||
"\n");
|
||||
|
||||
for (i = 0; i < handoffs->len; i++) {
|
||||
printf("void %s(void);\n", (char *)handoffs->pdata[i]);
|
||||
}
|
||||
printf("\n"
|
||||
"dissector_reg_t dissector_reg_handoff[] = {\n");
|
||||
for (i = 0; i < handoffs->len; i++) {
|
||||
printf(" { \"%s\", %s },\n", (char *)handoffs->pdata[i], (char *)handoffs->pdata[i]);
|
||||
}
|
||||
printf(" { NULL, NULL }\n"
|
||||
"};\n");
|
||||
|
||||
g_regex_unref(protos_regex);
|
||||
g_regex_unref(handoffs_regex);
|
||||
|
||||
g_ptr_array_free(protos, TRUE);
|
||||
g_ptr_array_free(handoffs, TRUE);
|
||||
}
|
||||
|
||||
/*
|
||||
* Editor modelines
|
||||
*
|
||||
* Local Variables:
|
||||
* c-basic-offset: 4
|
||||
* tab-width: 8
|
||||
* indent-tabs-mode: nil
|
||||
* End:
|
||||
*
|
||||
* ex: set shiftwidth=4 tabstop=8 expandtab:
|
||||
* :indentSize=4:tabSize=8:noTabs=true:
|
||||
*/
|
|
@ -19,6 +19,7 @@
|
|||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
#
|
||||
|
||||
# TODO fix srvsvc wkssvc
|
||||
set(PIDL_DISSECTOR_NAMES
|
||||
atsvc
|
||||
clusapi
|
||||
|
@ -111,12 +112,6 @@ set(PIDL_DISSECTOR_wkssvc_EXTRA_DEPS
|
|||
)
|
||||
|
||||
set(PIDL_DISSECTOR_TARGETS)
|
||||
set(PIDL_DISSECTOR_SRC)
|
||||
# TODO fix these dissectors, remove this and update PIDL_DISSECTOR_NAMES above.
|
||||
list(APPEND PIDL_DISSECTOR_SRC
|
||||
packet-dcerpc-srvsvc.c
|
||||
packet-dcerpc-wkssvc.c
|
||||
)
|
||||
|
||||
foreach(PROTOCOL_NAME IN LISTS PIDL_DISSECTOR_NAMES)
|
||||
add_custom_command(
|
||||
|
@ -148,13 +143,8 @@ foreach(PROTOCOL_NAME IN LISTS PIDL_DISSECTOR_NAMES)
|
|||
list(APPEND PIDL_DISSECTOR_TARGETS
|
||||
generate_dissector-dcerpc-${PROTOCOL_NAME}
|
||||
)
|
||||
list(APPEND PIDL_DISSECTOR_SRC
|
||||
packet-dcerpc-${PROTOCOL_NAME}.c
|
||||
)
|
||||
endforeach()
|
||||
|
||||
set(PIDL_DISSECTOR_SRC ${PIDL_DISSECTOR_SRC} PARENT_SCOPE)
|
||||
|
||||
add_custom_target(pidl-dissectors ALL DEPENDS ${PIDL_DISSECTOR_TARGETS})
|
||||
set_target_properties(pidl-dissectors
|
||||
PROPERTIES FOLDER "Generated Dissectors/PIDL"
|
||||
|
|
|
@ -174,9 +174,9 @@ CPP_FILES = \
|
|||
# a plugin.c file for a plugin.
|
||||
# All subsequent arguments are the files to scan.
|
||||
#
|
||||
plugin.c: $(REGISTER_SRC_FILES) $(top_srcdir)/tools/make-dissector-reg.py
|
||||
plugin.c: $(REGISTER_SRC_FILES) $(top_srcdir)/tools/make-plugin-reg.py
|
||||
@echo Making plugin.c
|
||||
@$(PYTHON) $(top_srcdir)/tools/make-dissector-reg.py $(srcdir) \
|
||||
@$(PYTHON) $(top_srcdir)/tools/make-plugin-reg.py $(srcdir) \
|
||||
plugin $(REGISTER_SRC_FILES)
|
||||
|
||||
checkapi:
|
||||
|
|
|
@ -29,7 +29,7 @@ static void set_cb_name(const char *proto) {
|
|||
static void *
|
||||
register_all_protocols_worker(void *arg _U_)
|
||||
{
|
||||
for (gulong i = 0; i < dissector_reg_proto_count(); i++) {
|
||||
for (gulong i = 0; i < dissector_reg_proto_count; i++) {
|
||||
set_cb_name(dissector_reg_proto[i].cb_name);
|
||||
dissector_reg_proto[i].cb_func();
|
||||
}
|
||||
|
@ -67,7 +67,7 @@ register_all_protocols(register_cb cb, gpointer cb_data)
|
|||
static void *
|
||||
register_all_protocol_handoffs_worker(void *arg _U_)
|
||||
{
|
||||
for (gulong i = 0; i < dissector_reg_handoff_count(); i++) {
|
||||
for (gulong i = 0; i < dissector_reg_handoff_count; i++) {
|
||||
set_cb_name(dissector_reg_handoff[i].cb_name);
|
||||
dissector_reg_handoff[i].cb_func();
|
||||
}
|
||||
|
@ -106,7 +106,7 @@ register_all_protocol_handoffs(register_cb cb, gpointer cb_data)
|
|||
|
||||
gulong register_count(void)
|
||||
{
|
||||
return dissector_reg_proto_count() + dissector_reg_handoff_count();
|
||||
return dissector_reg_proto_count + dissector_reg_handoff_count;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -62,8 +62,8 @@ EXTRA_DIST = \
|
|||
list_protos_in_cap.sh \
|
||||
macos-setup.sh \
|
||||
macos-setup-brew.sh \
|
||||
make-dissector-reg.py \
|
||||
make-manuf \
|
||||
make-plugin-reg.py \
|
||||
make-sminmpec.pl \
|
||||
make-services.py \
|
||||
make-tap-reg.py \
|
||||
|
|
|
@ -1,330 +0,0 @@
|
|||
#!/usr/bin/env python
|
||||
#
|
||||
# Looks for registration routines in the protocol dissectors,
|
||||
# and assembles C code to call all the routines.
|
||||
#
|
||||
# This is a Python version of the make-reg-dotc shell script.
|
||||
# Running the shell script on Win32 is very very slow because of
|
||||
# all the process-launching that goes on --- multiple greps and
|
||||
# seds for each input file. I wrote this python version so that
|
||||
# less processes would have to be started.
|
||||
|
||||
import os
|
||||
import sys
|
||||
import re
|
||||
import pickle
|
||||
import hashlib
|
||||
from stat import *
|
||||
|
||||
VERSION_KEY = '_VERSION'
|
||||
CUR_VERSION = 'this_is_useless_with_git'
|
||||
|
||||
#
|
||||
# The first argument is the directory in which the source files live.
|
||||
#
|
||||
srcdir = sys.argv[1]
|
||||
|
||||
#
|
||||
# The second argument is either "plugin" or "dissectors"; if it's
|
||||
# "plugin", we build a plugin.c for a plugin, and if it's
|
||||
# "dissectors", we build a register.c for libwireshark.
|
||||
#
|
||||
registertype = sys.argv[2]
|
||||
if registertype in ("plugin", "plugin_wtap"):
|
||||
final_filename = "plugin.c"
|
||||
cache_filename = None
|
||||
preamble = """\
|
||||
/*
|
||||
* Do not modify this file. Changes will be overwritten.
|
||||
*
|
||||
* Generated automatically from %s.
|
||||
*/
|
||||
""" % (sys.argv[0])
|
||||
elif registertype in ("dissectors", "dissectorsinfile"):
|
||||
final_filename = "dissectors.c"
|
||||
cache_filename = "dissectors-cache.pkl"
|
||||
preamble = """\
|
||||
/*
|
||||
* Do not modify this file. Changes will be overwritten.
|
||||
*
|
||||
* Generated automatically by the "register.c" target in
|
||||
* epan/dissectors/Makefile using %s
|
||||
* and information in epan/dissectors/register-cache.pkl.
|
||||
*
|
||||
* You can force this file to be regenerated completely by deleting
|
||||
* it along with epan/dissectors/register-cache.pkl.
|
||||
*/
|
||||
""" % (sys.argv[0])
|
||||
else:
|
||||
print(("Unknown output type '%s'" % registertype))
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
#
|
||||
# All subsequent arguments are the files to scan
|
||||
# or the name of a file containing the files to scan
|
||||
#
|
||||
if registertype == "dissectorsinfile":
|
||||
try:
|
||||
dissector_f = open(sys.argv[3])
|
||||
except IOError:
|
||||
print(("Unable to open input file '%s'" % sys.argv[3]))
|
||||
sys.exit(1)
|
||||
|
||||
files = [line.rstrip() for line in dissector_f]
|
||||
else:
|
||||
files = sys.argv[3:]
|
||||
|
||||
# Create the proper list of filenames
|
||||
filenames = []
|
||||
for file in files:
|
||||
if os.path.isfile(file):
|
||||
filenames.append(file)
|
||||
else:
|
||||
filenames.append(os.path.join(srcdir, file))
|
||||
|
||||
if len(filenames) < 1:
|
||||
print("No files found")
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
# Look through all files, applying the regex to each line.
|
||||
# If the pattern matches, save the "symbol" section to the
|
||||
# appropriate set.
|
||||
regs = {
|
||||
'proto_reg': set(),
|
||||
'handoff_reg': set(),
|
||||
'wtap_register': set(),
|
||||
}
|
||||
|
||||
# For those that don't know Python, r"" indicates a raw string,
|
||||
# devoid of Python escapes.
|
||||
proto_regex = r"(?P<symbol>\bproto_register_[_A-Za-z0-9]+)\s*\(\s*void\s*\)[^;]*$"
|
||||
|
||||
handoff_regex = r"(?P<symbol>\bproto_reg_handoff_[_A-Za-z0-9]+)\s*\(\s*void\s*\)[^;]*$"
|
||||
|
||||
wtap_reg_regex = r"(?P<symbol>\bwtap_register_[_A-Za-z0-9]+)\s*\([^;]+$"
|
||||
|
||||
# This table drives the pattern-matching and symbol-harvesting
|
||||
patterns = [
|
||||
( 'proto_reg', re.compile(proto_regex, re.MULTILINE) ),
|
||||
( 'handoff_reg', re.compile(handoff_regex, re.MULTILINE) ),
|
||||
( 'wtap_register', re.compile(wtap_reg_regex, re.MULTILINE) ),
|
||||
]
|
||||
|
||||
# Open our registration symbol cache
|
||||
cache = None
|
||||
if cache_filename:
|
||||
try:
|
||||
cache_file = open(cache_filename, 'rb')
|
||||
cache = pickle.load(cache_file)
|
||||
cache_file.close()
|
||||
if VERSION_KEY not in cache or cache[VERSION_KEY] != CUR_VERSION:
|
||||
cache = {VERSION_KEY: CUR_VERSION}
|
||||
except:
|
||||
cache = {VERSION_KEY: CUR_VERSION}
|
||||
|
||||
print(("Registering %d files, %d cached" % (len(filenames), len(list(cache.keys()))-1)))
|
||||
|
||||
# Grep
|
||||
cache_hits = 0
|
||||
cache_misses = 0
|
||||
for filename in filenames:
|
||||
file = open(filename)
|
||||
cur_mtime = os.fstat(file.fileno())[ST_MTIME]
|
||||
if cache and filename in cache:
|
||||
cdict = cache[filename]
|
||||
if cur_mtime == cdict['mtime']:
|
||||
cache_hits += 1
|
||||
# print "Pulling %s from cache" % (filename)
|
||||
regs['proto_reg'] |= set(cdict['proto_reg'])
|
||||
regs['handoff_reg'] |= set(cdict['handoff_reg'])
|
||||
regs['wtap_register'] |= set(cdict['wtap_register'])
|
||||
file.close()
|
||||
continue
|
||||
# We don't have a cache entry
|
||||
if cache is not None:
|
||||
cache_misses += 1
|
||||
cache[filename] = {
|
||||
'mtime': cur_mtime,
|
||||
'proto_reg': [],
|
||||
'handoff_reg': [],
|
||||
'wtap_register': [],
|
||||
}
|
||||
# print "Searching %s" % (filename)
|
||||
# Read the whole file into memory
|
||||
contents = file.read()
|
||||
for action in patterns:
|
||||
regex = action[1]
|
||||
for match in regex.finditer(contents):
|
||||
symbol = match.group("symbol")
|
||||
sym_type = action[0]
|
||||
regs[sym_type].add(symbol)
|
||||
if cache is not None:
|
||||
# print "Caching %s for %s: %s" % (sym_type, filename, symbol)
|
||||
cache[filename][sym_type].append(symbol)
|
||||
# We're done with the file contents
|
||||
del contents
|
||||
file.close()
|
||||
|
||||
|
||||
if cache is not None and cache_filename is not None:
|
||||
cache_file = open(cache_filename, 'wb')
|
||||
pickle.dump(cache, cache_file)
|
||||
cache_file.close()
|
||||
print(("Cache hits: %d, misses: %d" % (cache_hits, cache_misses)))
|
||||
|
||||
# Make sure we actually processed something
|
||||
if len(regs['proto_reg']) < 1:
|
||||
print("No protocol registrations found")
|
||||
sys.exit(1)
|
||||
|
||||
# Convert the sets into sorted lists to make the output pretty
|
||||
regs['proto_reg'] = sorted(regs['proto_reg'])
|
||||
regs['handoff_reg'] = sorted(regs['handoff_reg'])
|
||||
regs['wtap_register'] = sorted(regs['wtap_register'])
|
||||
|
||||
reg_code = ""
|
||||
|
||||
reg_code += preamble
|
||||
|
||||
# Make the routine to register all protocols
|
||||
if registertype == "plugin" or registertype == "plugin_wtap":
|
||||
reg_code += """
|
||||
#include "config.h"
|
||||
|
||||
#include <gmodule.h>
|
||||
|
||||
#include "moduleinfo.h"
|
||||
|
||||
/* plugins are DLLs */
|
||||
#define WS_BUILD_DLL
|
||||
#include "ws_symbol_export.h"
|
||||
|
||||
WS_DLL_PUBLIC_DEF void plugin_register (void);
|
||||
|
||||
WS_DLL_PUBLIC_DEF const gchar plugin_version[] = VERSION;
|
||||
WS_DLL_PUBLIC_DEF const gchar plugin_release[] = VERSION_RELEASE;
|
||||
|
||||
"""
|
||||
for symbol in regs['proto_reg']:
|
||||
reg_code += "extern void %s(void);\n" % (symbol)
|
||||
|
||||
reg_code += """
|
||||
WS_DLL_PUBLIC_DEF void
|
||||
plugin_register (void)
|
||||
{
|
||||
"""
|
||||
|
||||
for symbol in regs['proto_reg']:
|
||||
reg_code += " %s();\n" % (symbol)
|
||||
|
||||
reg_code += "}\n\n"
|
||||
|
||||
for symbol in regs['handoff_reg']:
|
||||
reg_code += "extern void %s(void);\n" % (symbol)
|
||||
|
||||
reg_code += """
|
||||
WS_DLL_PUBLIC_DEF void plugin_reg_handoff(void);
|
||||
|
||||
WS_DLL_PUBLIC_DEF void
|
||||
plugin_reg_handoff(void)
|
||||
{
|
||||
"""
|
||||
for symbol in regs['handoff_reg']:
|
||||
reg_code += " %s();\n" % (symbol)
|
||||
reg_code += "}\n"
|
||||
|
||||
if registertype == "plugin_wtap":
|
||||
reg_code += """
|
||||
WS_DLL_PUBLIC_DEF void
|
||||
register_wtap_module(void)
|
||||
{
|
||||
"""
|
||||
for symbol in regs['wtap_register']:
|
||||
reg_code += " {extern void %s (void); %s ();}\n" % (symbol, symbol)
|
||||
reg_code += """
|
||||
}
|
||||
"""
|
||||
|
||||
else:
|
||||
|
||||
reg_code += "\n#include <ws_symbol_export.h>"
|
||||
reg_code += "\n#include <dissectors.h>"
|
||||
reg_code += "\n"
|
||||
|
||||
for i in range(len(regs['proto_reg'])):
|
||||
reg_code += "\nvoid %s(void);" % regs['proto_reg'][i]
|
||||
|
||||
reg_code += "\n\ndissector_reg_t dissector_reg_proto[] = {\n"
|
||||
|
||||
reg_code += " { \"%s\", %s }" % (regs['proto_reg'][0], regs['proto_reg'][0])
|
||||
for i in range(1, len(regs['proto_reg'])):
|
||||
reg_code += ",\n { \"%s\", %s }" % (regs['proto_reg'][i], regs['proto_reg'][i])
|
||||
|
||||
reg_code += "\n};\n"
|
||||
|
||||
for i in range(len(regs['handoff_reg'])):
|
||||
reg_code += "\nvoid %s(void);" % regs['handoff_reg'][i]
|
||||
|
||||
reg_code += "\n\n\ndissector_reg_t dissector_reg_handoff[] = {\n"
|
||||
|
||||
reg_code += " { \"%s\", %s }" % (regs['handoff_reg'][0], regs['handoff_reg'][0])
|
||||
for i in range(1, len(regs['handoff_reg'])):
|
||||
reg_code += ",\n { \"%s\", %s }" % (regs['handoff_reg'][i], regs['handoff_reg'][i])
|
||||
|
||||
reg_code += "\n};\n"
|
||||
|
||||
reg_code += """
|
||||
gulong dissector_reg_proto_count(void)
|
||||
{
|
||||
return %(proto_reg_len)d;
|
||||
}
|
||||
|
||||
gulong dissector_reg_handoff_count(void)
|
||||
{
|
||||
return %(handoff_reg_len)d;
|
||||
}
|
||||
""" % {
|
||||
'proto_reg_len': len(regs['proto_reg']),
|
||||
'handoff_reg_len': len(regs['handoff_reg'])
|
||||
}
|
||||
|
||||
# Compare current and new content and update the file if anything has changed.
|
||||
|
||||
try: # Python >= 2.6, >= 3.0
|
||||
reg_code_bytes = bytes(reg_code.encode('utf-8'))
|
||||
except:
|
||||
reg_code_bytes = reg_code
|
||||
|
||||
new_hash = hashlib.sha1(reg_code_bytes).hexdigest()
|
||||
|
||||
try:
|
||||
fh = open(final_filename, 'rb')
|
||||
cur_hash = hashlib.sha1(fh.read()).hexdigest()
|
||||
fh.close()
|
||||
except:
|
||||
cur_hash = ''
|
||||
|
||||
try:
|
||||
if new_hash != cur_hash:
|
||||
print(('Updating ' + final_filename))
|
||||
fh = open(final_filename, 'w')
|
||||
fh.write(reg_code)
|
||||
fh.close()
|
||||
else:
|
||||
print((final_filename + ' unchanged.'))
|
||||
except OSError:
|
||||
sys.exit('Unable to write ' + final_filename + '.\n')
|
||||
|
||||
#
|
||||
# Editor modelines - http://www.wireshark.org/tools/modelines.html
|
||||
#
|
||||
# Local variables:
|
||||
# c-basic-offset: 4
|
||||
# indent-tabs-mode: nil
|
||||
# End:
|
||||
#
|
||||
# vi: set shiftwidth=4 expandtab:
|
||||
# :indentSize=4:noTabs=true:
|
||||
#
|
|
@ -0,0 +1,197 @@
|
|||
#!/usr/bin/env python
|
||||
#
|
||||
# Looks for registration routines in the plugin dissectors,
|
||||
# and assembles C code to call all the routines.
|
||||
#
|
||||
|
||||
import os
|
||||
import sys
|
||||
import re
|
||||
import hashlib
|
||||
from stat import *
|
||||
|
||||
#
|
||||
# The first argument is the directory in which the source files live.
|
||||
#
|
||||
srcdir = sys.argv[1]
|
||||
#
|
||||
# The second argument is either "plugin" or "plugin_wtap".
|
||||
#
|
||||
registertype = sys.argv[2]
|
||||
#
|
||||
# All subsequent arguments are the files to scan.
|
||||
#
|
||||
files = sys.argv[3:]
|
||||
|
||||
final_filename = "plugin.c"
|
||||
preamble = """\
|
||||
/*
|
||||
* Do not modify this file. Changes will be overwritten.
|
||||
*
|
||||
* Generated automatically from %s.
|
||||
*/
|
||||
""" % (sys.argv[0])
|
||||
|
||||
# Create the proper list of filenames
|
||||
filenames = []
|
||||
for file in files:
|
||||
if os.path.isfile(file):
|
||||
filenames.append(file)
|
||||
else:
|
||||
filenames.append(os.path.join(srcdir, file))
|
||||
|
||||
if len(filenames) < 1:
|
||||
print("No files found")
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
# Look through all files, applying the regex to each line.
|
||||
# If the pattern matches, save the "symbol" section to the
|
||||
# appropriate set.
|
||||
regs = {
|
||||
'proto_reg': set(),
|
||||
'handoff_reg': set(),
|
||||
'wtap_register': set(),
|
||||
}
|
||||
|
||||
# For those that don't know Python, r"" indicates a raw string,
|
||||
# devoid of Python escapes.
|
||||
proto_regex = r"(?P<symbol>\bproto_register_[_A-Za-z0-9]+)\s*\(\s*void\s*\)[^;]*$"
|
||||
|
||||
handoff_regex = r"(?P<symbol>\bproto_reg_handoff_[_A-Za-z0-9]+)\s*\(\s*void\s*\)[^;]*$"
|
||||
|
||||
wtap_reg_regex = r"(?P<symbol>\bwtap_register_[_A-Za-z0-9]+)\s*\([^;]+$"
|
||||
|
||||
# This table drives the pattern-matching and symbol-harvesting
|
||||
patterns = [
|
||||
( 'proto_reg', re.compile(proto_regex, re.MULTILINE) ),
|
||||
( 'handoff_reg', re.compile(handoff_regex, re.MULTILINE) ),
|
||||
( 'wtap_register', re.compile(wtap_reg_regex, re.MULTILINE) ),
|
||||
]
|
||||
|
||||
# Grep
|
||||
for filename in filenames:
|
||||
file = open(filename)
|
||||
cur_mtime = os.fstat(file.fileno())[ST_MTIME]
|
||||
# Read the whole file into memory
|
||||
contents = file.read()
|
||||
for action in patterns:
|
||||
regex = action[1]
|
||||
for match in regex.finditer(contents):
|
||||
symbol = match.group("symbol")
|
||||
sym_type = action[0]
|
||||
regs[sym_type].add(symbol)
|
||||
# We're done with the file contents
|
||||
del contents
|
||||
file.close()
|
||||
|
||||
# Make sure we actually processed something
|
||||
if len(regs['proto_reg']) < 1:
|
||||
print("No protocol registrations found")
|
||||
sys.exit(1)
|
||||
|
||||
# Convert the sets into sorted lists to make the output pretty
|
||||
regs['proto_reg'] = sorted(regs['proto_reg'])
|
||||
regs['handoff_reg'] = sorted(regs['handoff_reg'])
|
||||
regs['wtap_register'] = sorted(regs['wtap_register'])
|
||||
|
||||
reg_code = ""
|
||||
|
||||
reg_code += preamble
|
||||
|
||||
reg_code += """
|
||||
#include "config.h"
|
||||
|
||||
#include <gmodule.h>
|
||||
|
||||
#include "moduleinfo.h"
|
||||
|
||||
/* plugins are DLLs */
|
||||
#define WS_BUILD_DLL
|
||||
#include "ws_symbol_export.h"
|
||||
|
||||
WS_DLL_PUBLIC_DEF void plugin_register (void);
|
||||
|
||||
WS_DLL_PUBLIC_DEF const gchar plugin_version[] = VERSION;
|
||||
WS_DLL_PUBLIC_DEF const gchar plugin_release[] = VERSION_RELEASE;
|
||||
|
||||
"""
|
||||
|
||||
for symbol in regs['proto_reg']:
|
||||
reg_code += "extern void %s(void);\n" % (symbol)
|
||||
|
||||
reg_code += """
|
||||
WS_DLL_PUBLIC_DEF void
|
||||
plugin_register (void)
|
||||
{
|
||||
"""
|
||||
|
||||
for symbol in regs['proto_reg']:
|
||||
reg_code += " %s();\n" % (symbol)
|
||||
|
||||
reg_code += "}\n\n"
|
||||
|
||||
for symbol in regs['handoff_reg']:
|
||||
reg_code += "extern void %s(void);\n" % (symbol)
|
||||
|
||||
reg_code += """
|
||||
WS_DLL_PUBLIC_DEF void plugin_reg_handoff(void);
|
||||
|
||||
WS_DLL_PUBLIC_DEF void
|
||||
plugin_reg_handoff(void)
|
||||
{
|
||||
"""
|
||||
|
||||
for symbol in regs['handoff_reg']:
|
||||
reg_code += " %s();\n" % (symbol)
|
||||
reg_code += "}\n"
|
||||
|
||||
if registertype == "plugin_wtap":
|
||||
reg_code += """
|
||||
WS_DLL_PUBLIC_DEF void
|
||||
register_wtap_module(void)
|
||||
{
|
||||
"""
|
||||
|
||||
for symbol in regs['wtap_register']:
|
||||
reg_code += " {extern void %s (void); %s ();}\n" % (symbol, symbol)
|
||||
reg_code += "}"
|
||||
|
||||
# Compare current and new content and update the file if anything has changed.
|
||||
|
||||
try: # Python >= 2.6, >= 3.0
|
||||
reg_code_bytes = bytes(reg_code.encode('utf-8'))
|
||||
except:
|
||||
reg_code_bytes = reg_code
|
||||
|
||||
new_hash = hashlib.sha1(reg_code_bytes).hexdigest()
|
||||
|
||||
try:
|
||||
fh = open(final_filename, 'rb')
|
||||
cur_hash = hashlib.sha1(fh.read()).hexdigest()
|
||||
fh.close()
|
||||
except:
|
||||
cur_hash = ''
|
||||
|
||||
try:
|
||||
if new_hash != cur_hash:
|
||||
print(('Updating ' + final_filename))
|
||||
fh = open(final_filename, 'w')
|
||||
fh.write(reg_code)
|
||||
fh.close()
|
||||
else:
|
||||
print((final_filename + ' unchanged.'))
|
||||
except OSError:
|
||||
sys.exit('Unable to write ' + final_filename + '.\n')
|
||||
|
||||
#
|
||||
# Editor modelines - http://www.wireshark.org/tools/modelines.html
|
||||
#
|
||||
# Local variables:
|
||||
# c-basic-offset: 4
|
||||
# indent-tabs-mode: nil
|
||||
# End:
|
||||
#
|
||||
# vi: set shiftwidth=4 expandtab:
|
||||
# :indentSize=4:noTabs=true:
|
||||
#
|
Loading…
Reference in New Issue