src: rewrite driver impl checker in Python

As part of a goal to eliminate Perl from libvirt build tools,
rewrite the check-driverimpls.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 <crobinso@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
This commit is contained in:
Daniel P. Berrangé 2019-08-30 13:22:54 +01:00
parent 4a5370ba41
commit c2d6e61d5a
4 changed files with 106 additions and 82 deletions

View File

@ -49,6 +49,7 @@ EXTRA_DIST = \
build-aux/check-spacing.pl \
scripts/check-aclperms.py \
scripts/check-drivername.py \
scripts/check-driverimpls.py \
scripts/check-symfile.py \
scripts/check-symsorting.py \
scripts/dtrace2systemtap.py \

103
scripts/check-driverimpls.py Executable file
View File

@ -0,0 +1,103 @@
#!/usr/bin/env python
#
# Copyright (C) 2013-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 sys
def checkdriverimpls(filename):
intable = False
mainprefix = None
errs = False
with open(filename, "r") as fh:
lineno = 0
for line in fh:
lineno = lineno + 1
if intable:
if line.find("}") != -1:
intable = False
mainprefix = None
continue
m = re.search(r'''\.(\w+)\s*=\s*(\w+),?''', line)
if m is not None:
api = m.group(1)
impl = m.group(2)
if api in ["no", "name"]:
continue
if impl in ["NULL"]:
continue
suffix = impl
prefix = re.sub(r'''^([a-z]+)(.*?)$''', r'''\1''', impl)
if mainprefix is not None:
if mainprefix != prefix:
print(("%s:%d Bad prefix '%s' for API '%s', " +
"expecting '%s'") %
(filename, lineno, prefix, api, mainprefix),
file=sys.stderr)
errs = True
else:
mainprefix = prefix
if not api.startswith(mainprefix):
suffix = re.sub(r'''^[a-z]+''', "", suffix)
suffix = re.sub(r'''^([A-Z]+)''',
lambda m: m.group(1).lower(), suffix)
if api != suffix:
want = api
if want.startswith("nwf"):
want = "NWF" + want[3:]
if not api.startswith(mainprefix):
want = re.sub(r'''^([a-z])''',
lambda m: m.group(1).upper(), want)
want = mainprefix + want
print(("%s:%d Bad impl name '%s' for API " +
"'%s', expecting '%s'") %
(filename, lineno, impl, api, want),
file=sys.stderr)
errs = True
else:
m = re.search(r'''^(?:static\s+)?(vir(?:\w+)?Driver)''' +
r'''\s+(?!.*;)''', line)
if m is not None:
drv = m.group(1)
if drv in [
"virNWFilterCallbackDriver",
"virNWFilterTechDriver",
"virConnectDriver"]:
continue
intable = True
return errs
status = 0
for filename in sys.argv[1:]:
if checkdriverimpls(filename):
status = 1
sys.exit(status)

View File

@ -350,7 +350,7 @@ check-drivername:
$(srcdir)/libvirt_lxc.syms
check-driverimpls:
$(AM_V_GEN)$(PERL) $(srcdir)/check-driverimpls.pl \
$(AM_V_GEN)$(RUNUTF8) $(PYTHON) $(top_srcdir)/scripts/check-driverimpls.py \
$(DRIVER_SOURCE_FILES)
check-aclrules:
@ -363,7 +363,7 @@ check-aclperms:
$(srcdir)/access/viraccessperm.h \
$(srcdir)/access/viraccessperm.c
EXTRA_DIST += check-driverimpls.pl check-aclrules.pl
EXTRA_DIST += check-aclrules.pl
check-local: check-protocol check-symfile check-symsorting \
check-drivername check-driverimpls check-aclrules \

View File

@ -1,80 +0,0 @@
#!/usr/bin/env perl
#
# Copyright (C) 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/>.
#
use strict;
use warnings;
my $intable = 0;
my $table;
my $mainprefix;
my $status = 0;
while (<>) {
if ($intable) {
if (/}/) {
$intable = 0;
$table = undef;
$mainprefix = undef;
} elsif (/\.(\w+)\s*=\s*(\w+),?/) {
my $api = $1;
my $impl = $2;
next if $api eq "no";
next if $api eq "name";
next if $impl eq "NULL";
my $suffix = $impl;
my $prefix = $impl;
$prefix =~ s/^([a-z]+)(.*?)$/$1/;
if (defined $mainprefix) {
if ($mainprefix ne $prefix) {
print "$ARGV:$. Bad prefix '$prefix' for API '$api', expecting '$mainprefix'\n";
$status = 1;
}
} else {
$mainprefix = $prefix;
}
if ($api !~ /^$mainprefix/) {
$suffix =~ s/^[a-z]+//;
$suffix =~ s/^([A-Z]+)/lc $1/e;
}
if ($api ne $suffix) {
my $want = $api;
$want =~ s/^nwf/NWF/;
if ($api !~ /^$mainprefix/) {
$want =~ s/^([a-z])/uc $1/e;
$want = $mainprefix . $want;
}
print "$ARGV:$. Bad impl name '$impl' for API '$api', expecting '$want'\n";
$status = 1;
}
}
} elsif (/^(?:static\s+)?(vir(?:\w+)?Driver)\s+(?!.*;)/) {
next if $1 eq "virNWFilterCallbackDriver" ||
$1 eq "virNWFilterTechDriver" ||
$1 eq "virConnectDriver";
$intable = 1;
$table = $1;
}
}
exit $status;