mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-07-06 09:55:46 +00:00
build-aux: rewrite mock inline checker in Python
As part of a goal to eliminate Perl from libvirt build tools, rewrite the mock-noinline.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:
parent
e136236158
commit
b7d00249ea
@ -49,7 +49,7 @@ EXTRA_DIST = \
|
|||||||
build-aux/check-spacing.pl \
|
build-aux/check-spacing.pl \
|
||||||
build-aux/header-ifdef.pl \
|
build-aux/header-ifdef.pl \
|
||||||
scripts/minimize-po.py \
|
scripts/minimize-po.py \
|
||||||
build-aux/mock-noinline.pl \
|
scripts/mock-noinline.py \
|
||||||
scripts/prohibit-duplicate-header.py \
|
scripts/prohibit-duplicate-header.py \
|
||||||
build-aux/syntax-check.mk \
|
build-aux/syntax-check.mk \
|
||||||
build-aux/useless-if-before-free \
|
build-aux/useless-if-before-free \
|
||||||
|
@ -1,75 +0,0 @@
|
|||||||
#!/usr/bin/env perl
|
|
||||||
|
|
||||||
my %noninlined;
|
|
||||||
my %mocked;
|
|
||||||
|
|
||||||
# Functions in public header don't get the noinline annotation
|
|
||||||
# so whitelist them here
|
|
||||||
$noninlined{"virEventAddTimeout"} = 1;
|
|
||||||
# This one confuses the script as its defined in the mock file
|
|
||||||
# but is actually just a local helper
|
|
||||||
$noninlined{"virMockStatRedirect"} = 1;
|
|
||||||
|
|
||||||
foreach my $arg (@ARGV) {
|
|
||||||
if ($arg =~ /\.h$/) {
|
|
||||||
#print "Scan header $arg\n";
|
|
||||||
&scan_annotations($arg);
|
|
||||||
} elsif ($arg =~ /mock\.c$/) {
|
|
||||||
#print "Scan mock $arg\n";
|
|
||||||
&scan_overrides($arg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
my $warned = 0;
|
|
||||||
foreach my $func (keys %mocked) {
|
|
||||||
next if exists $noninlined{$func};
|
|
||||||
|
|
||||||
$warned++;
|
|
||||||
print STDERR "$func is mocked at $mocked{$func} but missing noinline annotation\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
exit $warned ? 1 : 0;
|
|
||||||
|
|
||||||
|
|
||||||
sub scan_annotations {
|
|
||||||
my $file = shift;
|
|
||||||
|
|
||||||
open FH, $file or die "cannot read $file: $!";
|
|
||||||
|
|
||||||
my $func;
|
|
||||||
while (<FH>) {
|
|
||||||
if (/^\s*(\w+)\(/ || /^(?:\w+\*?\s+)+(?:\*\s*)?(\w+)\(/) {
|
|
||||||
my $name = $1;
|
|
||||||
if ($name !~ /(?:G_GNUC|ATTRIBUTE)/) {
|
|
||||||
$func = $name;
|
|
||||||
}
|
|
||||||
} elsif (/^\s*$/) {
|
|
||||||
$func = undef;
|
|
||||||
}
|
|
||||||
if (/G_GNUC_NO_INLINE/) {
|
|
||||||
if (defined $func) {
|
|
||||||
$noninlined{$func} = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
close FH
|
|
||||||
}
|
|
||||||
|
|
||||||
sub scan_overrides {
|
|
||||||
my $file = shift;
|
|
||||||
|
|
||||||
open FH, $file or die "cannot read $file: $!";
|
|
||||||
|
|
||||||
my $func;
|
|
||||||
while (<FH>) {
|
|
||||||
if (/^(\w+)\(/ || /^\w+\s*(?:\*\s*)?(\w+)\(/) {
|
|
||||||
my $name = $1;
|
|
||||||
if ($name =~ /^vir/) {
|
|
||||||
$mocked{$name} = "$file:$.";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
close FH
|
|
||||||
}
|
|
@ -2180,8 +2180,8 @@ spacing-check:
|
|||||||
{ echo '$(ME): incorrect formatting' 1>&2; exit 1; }
|
{ echo '$(ME): incorrect formatting' 1>&2; exit 1; }
|
||||||
|
|
||||||
mock-noinline:
|
mock-noinline:
|
||||||
$(AM_V_GEN)$(VC_LIST) | $(GREP) '\.[ch]$$' | xargs \
|
$(AM_V_GEN)$(VC_LIST) | $(GREP) '\.[ch]$$' | $(RUNUTF8) xargs \
|
||||||
$(PERL) $(top_srcdir)/build-aux/mock-noinline.pl
|
$(PYTHON) $(top_srcdir)/scripts/mock-noinline.py
|
||||||
|
|
||||||
header-ifdef:
|
header-ifdef:
|
||||||
$(AM_V_GEN)$(VC_LIST) | $(GREP) '\.[h]$$' | xargs \
|
$(AM_V_GEN)$(VC_LIST) | $(GREP) '\.[h]$$' | xargs \
|
||||||
|
84
scripts/mock-noinline.py
Normal file
84
scripts/mock-noinline.py
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
#
|
||||||
|
# Copyright (C) 2017-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
|
||||||
|
|
||||||
|
noninlined = {}
|
||||||
|
mocked = {}
|
||||||
|
|
||||||
|
# Functions in public header don't get the noinline annotation
|
||||||
|
# so whitelist them here
|
||||||
|
noninlined["virEventAddTimeout"] = True
|
||||||
|
# This one confuses the script as its defined in the mock file
|
||||||
|
# but is actually just a local helper
|
||||||
|
noninlined["virMockStatRedirect"] = True
|
||||||
|
|
||||||
|
|
||||||
|
def scan_annotations(filename):
|
||||||
|
with open(filename, "r") as fh:
|
||||||
|
func = None
|
||||||
|
for line in fh:
|
||||||
|
m = re.search(r'''^\s*(\w+)\(''', line)
|
||||||
|
if m is None:
|
||||||
|
m = re.search(r'''^(?:\w+\*?\s+)+(?:\*\s*)?(\w+)\(''', line)
|
||||||
|
if m is not None:
|
||||||
|
name = m.group(1)
|
||||||
|
if "ATTRIBUTE" not in name and "G_GNUC_" not in name:
|
||||||
|
func = name
|
||||||
|
elif line.isspace():
|
||||||
|
func = None
|
||||||
|
|
||||||
|
if "G_GNUC_NO_INLINE" in line:
|
||||||
|
if func is not None:
|
||||||
|
noninlined[func] = True
|
||||||
|
|
||||||
|
|
||||||
|
def scan_overrides(filename):
|
||||||
|
with open(filename, "r") as fh:
|
||||||
|
lineno = 0
|
||||||
|
for line in fh:
|
||||||
|
lineno = lineno + 1
|
||||||
|
|
||||||
|
m = re.search(r'''^(\w+)\(''', line)
|
||||||
|
if m is None:
|
||||||
|
m = re.search(r'''^\w+\s*(?:\*\s*)?(\w+)\(''', line)
|
||||||
|
if m is not None:
|
||||||
|
name = m.group(1)
|
||||||
|
if name.startswith("vir"):
|
||||||
|
mocked[name] = "%s:%d" % (filename, lineno)
|
||||||
|
|
||||||
|
|
||||||
|
for filename in sys.argv[1:]:
|
||||||
|
if filename.endswith(".h"):
|
||||||
|
scan_annotations(filename)
|
||||||
|
elif filename.endswith("mock.c"):
|
||||||
|
scan_overrides(filename)
|
||||||
|
|
||||||
|
warned = False
|
||||||
|
for func in mocked.keys():
|
||||||
|
if func not in noninlined:
|
||||||
|
warned = True
|
||||||
|
print("%s is mocked at %s but missing noinline annotation" %
|
||||||
|
(func, mocked[func]), file=sys.stderr)
|
||||||
|
|
||||||
|
if warned:
|
||||||
|
sys.exit(1)
|
||||||
|
sys.exit(0)
|
Loading…
Reference in New Issue
Block a user