As part of an goal to eliminate Perl from libvirt build tools,
rewrite the gensystemtap.pl tool in Python.
This was a straight conversion, manually going line-by-line to
change the syntax from Perl to Python. Thus the overall structure
of the file and approach is the same.
Signed-off-by: Daniel P. Berrangé <berrange(a)redhat.com>
---
cfg.mk | 4 +-
src/Makefile.am | 5 +-
src/rpc/Makefile.inc.am | 2 +-
src/rpc/gensystemtap.pl | 193 ----------------------------------------
src/rpc/gensystemtap.py | 174 ++++++++++++++++++++++++++++++++++++
5 files changed, 179 insertions(+), 199 deletions(-)
delete mode 100755 src/rpc/gensystemtap.pl
create mode 100755 src/rpc/gensystemtap.py
diff --git a/cfg.mk b/cfg.mk
index 3e63fee9ff..45b16ee8c3 100644
--- a/cfg.mk
+++ b/cfg.mk
@@ -407,6 +407,7 @@ sc_prohibit_risky_id_promotion:
# since gnulib has more guarantees for snprintf portability
sc_prohibit_sprintf:
@prohibit='\<[s]printf\>' \
+ in_vc_files='\.[ch]$$' \
halt='use snprintf, not sprintf' \
$(_sc_search_regexp)
@@ -1267,9 +1268,6 @@ exclude_file_name_regexp--sc_prohibit_readlink = \
exclude_file_name_regexp--sc_prohibit_setuid =
^src/util/virutil\.c|tools/virt-login-shell\.c$$
-exclude_file_name_regexp--sc_prohibit_sprintf = \
- ^(cfg\.mk|docs/hacking\.html\.in|.*\.stp|.*\.pl)$$
-
exclude_file_name_regexp--sc_prohibit_strncpy = ^src/util/virstring\.c$$
exclude_file_name_regexp--sc_prohibit_strtol = ^examples/.*$$
diff --git a/src/Makefile.am b/src/Makefile.am
index 8b046cafe4..539d8b0f58 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -636,8 +636,9 @@ RPC_PROBE_FILES += $(srcdir)/rpc/virnetprotocol.x \
$(srcdir)/remote/qemu_protocol.x \
$(srcdir)/admin/admin_protocol.x
-libvirt_functions.stp: $(RPC_PROBE_FILES) $(srcdir)/rpc/gensystemtap.pl
- $(AM_V_GEN)$(PERL) -w $(srcdir)/rpc/gensystemtap.pl $(RPC_PROBE_FILES) > $@
+libvirt_functions.stp: $(RPC_PROBE_FILES) $(srcdir)/rpc/gensystemtap.py
+ $(AM_V_GEN)$(RUNUTF8) $(PYTHON) $(srcdir)/rpc/gensystemtap.py \
+ $(RPC_PROBE_FILES) > $@
%_probes.stp: %_probes.d $(srcdir)/dtrace2systemtap.py \
$(top_builddir)/config.status
diff --git a/src/rpc/Makefile.inc.am b/src/rpc/Makefile.inc.am
index b8ca53c69a..b43ee4ab7a 100644
--- a/src/rpc/Makefile.inc.am
+++ b/src/rpc/Makefile.inc.am
@@ -3,7 +3,7 @@
EXTRA_DIST += \
rpc/gendispatch.pl \
rpc/genprotocol.pl \
- rpc/gensystemtap.pl \
+ rpc/gensystemtap.py \
rpc/virnetprotocol.x \
rpc/virkeepaliveprotocol.x \
$(NULL)
diff --git a/src/rpc/gensystemtap.pl b/src/rpc/gensystemtap.pl
deleted file mode 100755
index 6693d4d6f5..0000000000
--- a/src/rpc/gensystemtap.pl
+++ /dev/null
@@ -1,193 +0,0 @@
-#!/usr/bin/env perl
-#
-# Copyright (C) 2011-2012 Red Hat, Inc.
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library. If not, see
-# <
http://www.gnu.org/licenses/>.
-#
-# Generate a set of systemtap functions for translating various
-# RPC enum values into strings
-#
-# perl gensystemtap.pl */*.x > libvirt_functions.stp
-#
-
-use strict;
-
-my %funcs;
-
-my %type;
-my %status;
-my %auth;
-
-my $instatus = 0;
-my $intype = 0;
-my $inauth = 0;
-while (<>) {
- if (/enum\s+virNetMessageType/) {
- $intype = 1;
- } elsif (/enum\s+virNetMessageStatus/) {
- $instatus = 1;
- } elsif (/enum remote_auth_type/) {
- $inauth = 1;
- } elsif (/}/) {
- $instatus = $intype = $inauth = 0;
- } elsif ($instatus) {
- if (/^\s+VIR_NET_(\w+)\s*=\s*(\d+),?$/) {
- $status{$2} = lc $1;
- }
- } elsif ($intype) {
- if (/^\s+VIR_NET_(\w+)\s*=\s*(\d+),?$/) {
- $type{$2} = lc $1;
- }
- } elsif ($inauth) {
- if (/^\s+REMOTE_AUTH_(\w+)\s*=\s*(\d+),?$/) {
- $auth{$2} = lc $1;
- }
- } else {
- if (/(?:VIR_)?(\w+?)(?:_PROTOCOL)?_PROGRAM\s*=\s*0x([a-fA-F0-9]+)\s*;/) {
- $funcs{lc $1} = { id => hex($2), version => undef, progs => [] };
- } elsif
(/(?:VIR_)?(\w+?)(?:_PROTOCOL)?_(?:PROGRAM|PROTOCOL)_VERSION\s*=\s*(\d+)\s*;/) {
- $funcs{lc $1}->{version} = $2;
- } elsif (/(?:VIR_)?(\w+?)(?:_PROTOCOL)?_PROC_(.*?)\s+=\s+(\d+)/) {
- $funcs{lc $1}->{progs}->[$3] = lc $2;
- }
- }
-}
-
-print <<EOF;
-function libvirt_rpc_auth_name(type, verbose)
-{
-EOF
-my $first = 1;
-foreach my $type (sort(keys %auth)) {
- my $cond = $first ? "if" : "} else if";
- $first = 0;
- print " $cond (type == ", $type, ") {\n";
- print " typestr = \"", $auth{$type}, "\"\n";
-}
-print <<EOF;
- } else {
- typestr = "unknown";
- verbose = 1;
- }
- if (verbose) {
- typestr = typestr . sprintf(":%d", type)
- }
- return typestr;
-}
-EOF
-
-print <<EOF;
-function libvirt_rpc_type_name(type, verbose)
-{
-EOF
-$first = 1;
-foreach my $type (sort(keys %type)) {
- my $cond = $first ? "if" : "} else if";
- $first = 0;
- print " $cond (type == ", $type, ") {\n";
- print " typestr = \"", $type{$type}, "\"\n";
-}
-print <<EOF;
- } else {
- typestr = "unknown";
- verbose = 1;
- }
- if (verbose) {
- typestr = typestr . sprintf(":%d", type)
- }
- return typestr;
-}
-EOF
-
-print <<EOF;
-function libvirt_rpc_status_name(status, verbose)
-{
-EOF
-$first = 1;
-foreach my $status (sort(keys %status)) {
- my $cond = $first ? "if" : "} else if";
- $first = 0;
- print " $cond (status == ", $status, ") {\n";
- print " statusstr = \"", $status{$status},
"\"\n";
-}
-print <<EOF;
- } else {
- statusstr = "unknown";
- verbose = 1;
- }
- if (verbose) {
- statusstr = statusstr . sprintf(":%d", status)
- }
- return statusstr;
-}
-EOF
-
-print <<EOF;
-function libvirt_rpc_program_name(program, verbose)
-{
-EOF
-$first = 1;
-foreach my $prog (sort(keys %funcs)) {
- my $cond = $first ? "if" : "} else if";
- $first = 0;
- print " $cond (program == ", $funcs{$prog}->{id}, ") {\n";
- print " programstr = \"", $prog, "\"\n";
-}
-print <<EOF;
- } else {
- programstr = "unknown";
- verbose = 1;
- }
- if (verbose) {
- programstr = programstr . sprintf(":%d", program)
- }
- return programstr;
-}
-EOF
-
-
-print <<EOF;
-function libvirt_rpc_procedure_name(program, version, proc, verbose)
-{
-EOF
-$first = 1;
-foreach my $prog (sort(keys %funcs)) {
- my $cond = $first ? "if" : "} else if";
- $first = 0;
- print " $cond (program == ", $funcs{$prog}->{id}, " &&
version == ", $funcs{$prog}->{version}, ") {\n";
-
- my $pfirst = 1;
- for (my $id = 1 ; $id <= $#{$funcs{$prog}->{progs}} ; $id++) {
- my $cond = $pfirst ? "if" : "} else if";
- $pfirst = 0;
- print " $cond (proc == $id) {\n";
- print " procstr = \"",
$funcs{$prog}->{progs}->[$id], "\";\n";
- }
- print " } else {\n";
- print " procstr = \"unknown\";\n";
- print " verbose = 1;\n";
- print " }\n";
-}
-print <<EOF;
- } else {
- procstr = "unknown";
- verbose = 1;
- }
- if (verbose) {
- procstr = procstr . sprintf(":%d", proc)
- }
- return procstr;
-}
-EOF
diff --git a/src/rpc/gensystemtap.py b/src/rpc/gensystemtap.py
new file mode 100755
index 0000000000..4013c0969f
--- /dev/null
+++ b/src/rpc/gensystemtap.py
@@ -0,0 +1,174 @@
+#!/usr/bin/env python
+#
+# Copyright (C) 2011-2019 Red Hat, Inc.
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library. If not, see
+# <
http://www.gnu.org/licenses/>.
+#
+# Generate a set of systemtap functions for translating various
+# RPC enum values into strings
+#
+# python gensystemtap.py */*.x > libvirt_functions.stp
+#
+
+from __future__ import print_function
+
+import re
+import sys
+
+funcs = {}
+
+types = {}
+status = {}
+auth = {}
+
+def load_file(fh):
+ instatus = False
+ intype = False
+ inauth = False
+
+ for line in fh:
+ if re.match(r'''\s*enum\s+virNetMessageType\s*''',
line):
+ intype = True
+ elif re.match(r'''\s*enum\s+virNetMessageStatus\s*''',
line):
+ instatus = True
+ elif re.match(r'''\s*enum remote_auth_type.*''', line):
+ inauth = True
+ elif line.find("}") != -1:
+ intype = False
+ instatus = False
+ inauth = False
+ elif instatus:
+ m = re.match(r'''^\s+VIR_NET_(\w+)\s*=\s*(\d+),?$''',
line)
+ if m is not None:
+ status[m.group(2)] = m.group(1).lower()
+ elif intype:
+ m = re.match(r'''^\s+VIR_NET_(\w+)\s*=\s*(\d+),?$''',
line)
+ if m is not None:
+ types[m.group(2)] = m.group(1).lower()
+ elif inauth:
+ m =
re.match(r'''^\s+REMOTE_AUTH_(\w+)\s*=\s*(\d+),?$''', line)
+ if m is not None:
+ auth[m.group(2)] = m.group(1).lower()
+ else:
+ m =
re.match(r'''^.*?(?:VIR_)?(\w+?)(?:_PROTOCOL)?_PROGRAM\s*=\s*0x([a-fA-F0-9]+)\s*;''',
line)
+ if m is not None:
+ funcs[m.group(1).lower()] = {
+ "id": int(m.group(2), 16),
+ "version": None,
+ "progs": []
+ }
+ continue
+
+ m =
re.match(r'''^.*?(?:VIR_)?(\w+?)(?:_PROTOCOL)?_(?:PROGRAM|PROTOCOL)_VERSION\s*=\s*(\d+)\s*;''',
line)
+ if m is not None:
+ funcs[m.group(1).lower()]["version"] = m.group(2)
+ continue
+
+ m =
re.match(r'''^.*?(?:VIR_)?(\w+?)(?:_PROTOCOL)?_PROC_(.*?)\s+=\s+(\d+)''',
line)
+ if m is not None:
+ funcs[m.group(1).lower()]["progs"].insert(int(m.group(3)),
m.group(2).lower())
+
+for file in sys.argv[1:]:
+ with open(file, "r") as fh:
+ load_file(fh)
+
+
+def genfunc(name, varname, types):
+ print("function %s(%s, verbose)" % (name, varname))
+ print("{")
+
+ first = True
+ for typename in sorted(types.keys()):
+ cond = "} else if"
+ if first:
+ cond = "if"
+ first = False
+
+ print(" %s (%s == %s) {" % (cond, varname, typename))
+ print(" %sstr = \"%s\"" % (varname, types[typename]))
+
+ print(" } else {")
+ print(" %sstr = \"unknown\";" % varname)
+ print(" verbose = 1;")
+ print(" }")
+ print(" if (verbose) {")
+ print(" %sstr = %sstr . sprintf(\":%%d\", %s)" % (varname,
varname, varname))
+ print(" }")
+ print(" return %sstr;" % varname)
+ print("}")
+
+genfunc("libvirt_rpc_auth_name", "type", auth)
+genfunc("libvirt_rpc_type_name", "type", types)
+genfunc("libvirt_rpc_status_name", "status", status)
+
+print("function libvirt_rpc_program_name(program, verbose)")
+print("{")
+
+first = True
+for funcname in sorted(funcs.keys()):
+ cond = "} else if"
+ if first:
+ cond = "if"
+ first = False
+
+ print(" %s (program == %s) {" % (cond, funcs[funcname]["id"]))
+ print(" programstr = \"%s\"" % funcname)
+
+print(" } else {")
+print(" programstr = \"unknown\";")
+print(" verbose = 1;")
+print(" }")
+print(" if (verbose) {")
+print(" programstr = programstr . sprintf(\":%d\", program)")
+print(" }")
+print(" return programstr;")
+print("}")
+
+print("function libvirt_rpc_procedure_name(program, version, proc, verbose)")
+print("{")
+
+first = True
+for prog in sorted(funcs.keys()):
+ cond = "} else if"
+ if first:
+ cond = "if"
+ first = False
+
+ print(" %s (program == %s && version == %s) {" % (cond,
funcs[prog]["id"], funcs[prog]["version"]))
+
+ pfirst = True
+ for id in range(len(funcs[prog]["progs"])):
+ pcond = "} else if"
+ if pfirst:
+ pcond = "if"
+ pfirst = False
+
+ print(" %s (proc == %s) {" % (pcond, id + 1))
+ print(" procstr = \"%s\";" %
funcs[prog]["progs"][id])
+
+ print(" } else {")
+ print(" procstr = \"unknown\";")
+ print(" verbose = 1;")
+ print(" }")
+
+print(" } else {")
+print(" procstr = \"unknown\";")
+print(" verbose = 1;")
+print(" }")
+print(" if (verbose) {")
+print(" procstr = procstr . sprintf(\":%d\", proc)")
+print(" }")
+print(" return procstr;")
+print("}")
--
2.21.0