As part of an goal to eliminate Perl from libvirt build tools,
rewrite the check-symfile.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>
---
src/Makefile.am | 10 +++---
src/check-symfile.pl | 70 --------------------------------------
src/check-symfile.py | 81 ++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 86 insertions(+), 75 deletions(-)
delete mode 100755 src/check-symfile.pl
create mode 100755 src/check-symfile.py
diff --git a/src/Makefile.am b/src/Makefile.am
index 7c3e9ab981..d10bfdf448 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -274,11 +274,11 @@ PDWTAGS = \
# rule for libvirt.la. However, checking symbols relies on Linux ELF layout
if WITH_LINUX
check-symfile: libvirt.syms libvirt.la
- $(AM_V_GEN)$(PERL) $(srcdir)/check-symfile.pl libvirt.syms \
- .libs/libvirt.so
+ $(AM_V_GEN)$(RUNUTF8) $(PYTHON) $(srcdir)/check-symfile.py \
+ libvirt.syms .libs/libvirt.so
check-admin-symfile: libvirt_admin.syms libvirt-admin.la
- $(AM_V_GEN)$(PERL) $(srcdir)/check-symfile.pl libvirt_admin.syms \
- .libs/libvirt-admin.so
+ $(AM_V_GEN)$(RUNUTF8) $(PYTHON) $(srcdir)/check-symfile.py \
+ libvirt_admin.syms .libs/libvirt-admin.so
else ! WITH_LINUX
check-symfile:
check-admin-symfile:
@@ -289,7 +289,7 @@ check-symsorting:
check-admin-symsorting:
$(AM_V_GEN)$(RUNUTF8) $(PYTHON) $(srcdir)/check-symsorting.py \
$(srcdir) $(ADMIN_SYM_FILES)
-EXTRA_DIST += check-symfile.pl check-symsorting.py
+EXTRA_DIST += check-symfile.py check-symsorting.py
# Keep this list synced with RPC_PROBE_FILES
PROTOCOL_STRUCTS = \
diff --git a/src/check-symfile.pl b/src/check-symfile.pl
deleted file mode 100755
index 4f88300864..0000000000
--- a/src/check-symfile.pl
+++ /dev/null
@@ -1,70 +0,0 @@
-#!/usr/bin/env perl
-
-# Copyright (C) 2012-2013 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/>.
-
-die "syntax: $0 SYMFILE ELFLIB(S)" unless int(@ARGV) >= 2;
-
-my $symfile = shift @ARGV;
-my @elflibs = @ARGV;
-
-my %wantsyms;
-my %gotsyms;
-
-my $ret = 0;
-
-open SYMFILE, $symfile or die "cannot read $symfile: $!";
-
-while (<SYMFILE>) {
- next if /{/;
- next if /}/;
- next if /global:/;
- next if /local:/;
- next if /^\s*$/;
- next if /^\s*#/;
- next if /\*/;
-
- die "malformed line $_" unless /^\s*(\S+);$/;
-
- if (exists $wantsyms{$1}) {
- print STDERR "Symbol $1 is listed twice\n";
- $ret = 1;
- } else {
- $wantsyms{$1} = 1;
- }
-}
-close SYMFILE;
-
-foreach my $elflib (@elflibs) {
- open NM, "-|", "nm", $elflib or die "cannot run 'nm
$elflib': $!";
-
- while (<NM>) {
- next unless /^\S+\s(?:[TBD])\s(\S+)\s*$/;
-
- $gotsyms{$1} = 1;
- }
-
- close NM;
-}
-
-foreach my $sym (keys(%wantsyms)) {
- next if exists $gotsyms{$sym};
-
- print STDERR "Expected symbol $sym is not in ELF library\n";
- $ret = 1;
-}
-
-exit($ret);
diff --git a/src/check-symfile.py b/src/check-symfile.py
new file mode 100755
index 0000000000..0bb1c1e00d
--- /dev/null
+++ b/src/check-symfile.py
@@ -0,0 +1,81 @@
+#!/usr/bin/env python
+#
+# Copyright (C) 2012-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/>.
+
+from __future__ import print_function
+
+import re
+import subprocess
+import sys
+
+if len(sys.argv) < 3:
+ print("syntax: %s SYMFILE ELFLIB(S)" % sys.argv[0], file=sys.stderr)
+
+symfile = sys.argv[1]
+elflibs = sys.argv[2:]
+
+wantsyms = {}
+gotsyms = {}
+
+ret = 0
+
+with open(symfile, "r") as fh:
+ for line in fh:
+ line = line.strip()
+ if line.find("{") != -1:
+ continue
+ if line.find("}") != -1:
+ continue
+ if line in ["global:", "local:"]:
+ continue
+ if line == "":
+ continue
+ if line[0] == '#':
+ continue
+ if line.find("*") != -1:
+ continue
+
+ line = line.strip(";")
+
+ if line in wantsyms:
+ print("Symbol $1 is listed twice", file=sys.stderr)
+ ret = 1
+ else:
+ wantsyms[line] = True
+
+for elflib in elflibs:
+ nm = subprocess.Popen(["nm", elflib], shell=False,
+ stdout=subprocess.PIPE).stdout
+
+ symprog = re.compile(r'''^\S+\s(?:[TBD])\s(\S+)\s*$''')
+ for line in nm:
+ line = line.decode("utf-8")
+ symmatch = symprog.match(line)
+ if symmatch is None:
+ continue
+
+ gotsyms[symmatch.group(1)] = True
+
+
+for sym in wantsyms.keys():
+ if sym in gotsyms:
+ continue
+
+ print("Expected symbol '%s' is not in ELF library" % sym,
file=sys.stderr)
+ ret = 1
+
+sys.exit(ret)
--
2.21.0