From 31276b3b27394fd01cf5403fc48c4df161aba1f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= Date: Fri, 30 Aug 2019 13:22:54 +0100 Subject: [PATCH] src: rewrite symfile sorting checker in Python MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit As part of a goal to eliminate Perl from libvirt build tools, rewrite the check-symsorting.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. Tested-by: Cole Robinson Reviewed-by: Ján Tomko Signed-off-by: Daniel P. Berrangé --- Makefile.am | 1 + scripts/check-symsorting.py | 117 ++++++++++++++++++++++++++++++++++++ src/Makefile.am | 4 +- src/admin/Makefile.inc.am | 2 +- src/check-symsorting.pl | 106 -------------------------------- 5 files changed, 121 insertions(+), 109 deletions(-) create mode 100755 scripts/check-symsorting.py delete mode 100755 src/check-symsorting.pl diff --git a/Makefile.am b/Makefile.am index 53026f0d4b..df3b948213 100644 --- a/Makefile.am +++ b/Makefile.am @@ -48,6 +48,7 @@ EXTRA_DIST = \ scripts/augeas-gentest.py \ build-aux/check-spacing.pl \ scripts/check-aclperms.py \ + scripts/check-symsorting.py \ scripts/header-ifdef.py \ scripts/minimize-po.py \ scripts/mock-noinline.py \ diff --git a/scripts/check-symsorting.py b/scripts/check-symsorting.py new file mode 100755 index 0000000000..8e698c0657 --- /dev/null +++ b/scripts/check-symsorting.py @@ -0,0 +1,117 @@ +#!/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 +# . + +from __future__ import print_function + +import os.path +import re +import sys + +if len(sys.argv) < 3: + print("syntax: %s SRCDIR SYMFILE..." % sys.argv[0], file=sys.stderr) + sys.exit(1) + + +def check_sorting(group, symfile, line, groupfile, lastgroup): + sortedgroup = sorted(group, key=str.lower) + issorted = True + first = None + last = None + + err = False + # Check that groups are in order and groupfile exists + if lastgroup is not None and lastgroup.lower() > groupfile.lower(): + print("Symbol block at %s:%s: block not sorted" % + (symfile, line), file=sys.stderr) + print("Move %s block before %s block" % + (groupfile, lastgroup), file=sys.stderr) + print("", file=sys.stderr) + err = True + + if not os.path.exists(os.path.join(srcdir, groupfile)): + print("Symbol block at %s:%s: %s not found" % + (symfile, line, groupfile), file=sys.stderr) + print("", file=sys.stderr) + err = True + + # Check that symbols within a group are in order + for i in range(len(group)): + if sortedgroup[i] != group[i]: + if first is None: + first = i + + last = i + issorted = False + + if not issorted: + actual = group[first:(last - first + 1)] + expect = sortedgroup[first:(last - first + 1)] + print("Symbol block at %s:%s: symbols not sorted" % + (symfile, line), file=sys.stderr) + for g in actual: + print(" %s" % g, file=sys.stderr) + print("Correct ordering", file=sys.stderr) + for g in expect: + print(" %s" % g, file=sys.stderr) + print("", file=sys.stderr) + err = True + + return err + + +ret = 0 +srcdir = sys.argv[1] +lastgroup = None +for symfile in sys.argv[2:]: + with open(symfile, "r") as fh: + lineno = 0 + groupfile = "" + group = [] + thisline = 0 + + for line in fh: + thisline = thisline + 1 + line = line.strip() + + filenamematch = re.search(r'''^#\s*((\w+\/)*(\w+\.h))\s*$''', line) + if filenamematch is not None: + groupfile = filenamematch.group(1) + elif line == "": + if len(group) > 0: + if check_sorting(group, symfile, lineno, + groupfile, lastgroup): + ret = 1 + + group = [] + lineno = thisline + lastgroup = groupfile + elif line[0] == '#': + # Ignore comments + pass + else: + line = line.strip(";") + group.append(line) + + if len(group) > 0: + if check_sorting(group, symfile, lineno, + groupfile, lastgroup): + ret = 1 + + lastgroup = None + +sys.exit(ret) diff --git a/src/Makefile.am b/src/Makefile.am index 8df1d41c3c..2aa74dc84c 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -283,9 +283,9 @@ else ! WITH_LINUX check-symfile: endif ! WITH_LINUX check-symsorting: - $(AM_V_GEN)$(PERL) $(srcdir)/check-symsorting.pl \ + $(AM_V_GEN)$(RUNUTF8) $(PYTHON) $(top_srcdir)/scripts/check-symsorting.py \ $(srcdir) $(SYM_FILES) -EXTRA_DIST += check-symfile.pl check-symsorting.pl +EXTRA_DIST += check-symfile.pl # Keep this list synced with RPC_PROBE_FILES PROTOCOL_STRUCTS = \ diff --git a/src/admin/Makefile.inc.am b/src/admin/Makefile.inc.am index 3feb23aa20..97048df6f3 100644 --- a/src/admin/Makefile.inc.am +++ b/src/admin/Makefile.inc.am @@ -112,7 +112,7 @@ check-admin-symfile: endif ! WITH_LINUX check-admin-symsorting: - $(AM_V_GEN)$(PERL) $(srcdir)/check-symsorting.pl \ + $(AM_V_GEN)$(RUNUTF8) $(PYTHON) $(top_srcdir)/scripts/check-symsorting.py \ $(srcdir) $(ADMIN_SYM_FILES) check-admin-drivername: diff --git a/src/check-symsorting.pl b/src/check-symsorting.pl deleted file mode 100755 index 51e38bdedb..0000000000 --- a/src/check-symsorting.pl +++ /dev/null @@ -1,106 +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 -# . - -use strict; -use warnings; - -die "syntax: $0 SRCDIR SYMFILE..." unless int(@ARGV) >= 2; - -my $ret = 0; -my $srcdir = shift; -my $lastgroup = undef; -foreach my $symfile (@ARGV) { - open SYMFILE, $symfile or die "cannot read $symfile: $!"; - - my $line = 0; - my $groupfile = ""; - my @group; - - while () { - chomp; - - if (/^#\s*((\w+\/)*(\w+\.h))\s*$/) { - $groupfile = $1; - } elsif (/^#/) { - # Ignore comments - } elsif (/^\s*$/) { - if (@group) { - &check_sorting(\@group, $symfile, $line, $groupfile); - } - @group = (); - $line = $.; - } else { - $_ =~ s/;//; - push @group, $_; - } - } - - close SYMFILE; - if (@group) { - &check_sorting(\@group, $symfile, $line, $groupfile); - } - $lastgroup = undef; -} - -sub check_sorting { - my $group = shift; - my $symfile = shift; - my $line = shift; - my $groupfile = shift; - - my @group = @{$group}; - my @sorted = sort { lc $a cmp lc $b } @group; - my $sorted = 1; - my $first; - my $last; - - # Check that groups are in order and groupfile exists - if (defined $lastgroup && lc $lastgroup ge lc $groupfile) { - print "Symbol block at $symfile:$line: block not sorted\n"; - print "Move $groupfile block before $lastgroup block\n"; - print "\n"; - $ret = 1; - } - if (! -e "$srcdir/$groupfile") { - print "Symbol block at $symfile:$line: $groupfile not found\n"; - print "\n"; - $ret = 1; - } - $lastgroup = $groupfile; - - # Check that symbols within a group are in order - for (my $i = 0 ; $i <= $#sorted ; $i++) { - if ($sorted[$i] ne $group[$i]) { - $first = $i unless defined $first; - $last = $i; - $sorted = 0; - } - } - if (!$sorted) { - @group = splice @group, $first, ($last-$first+1); - @sorted = splice @sorted, $first, ($last-$first+1); - print "Symbol block at $symfile:$line: symbols not sorted\n"; - print map { " " . $_ . "\n" } @group; - print "Correct ordering\n"; - print map { " " . $_ . "\n" } @sorted; - print "\n"; - $ret = 1; - } -} - -exit $ret;