With most of new code using g_auto for cleanup, contributors
are used to most of the free fucntion handling NULL gracefully.
Also, despite finding some occurrences in current codebase:
avoid_if_before_free
~/libvirt/src/ch/ch_monitor.c: if (mon->vm)
virObjectUnref(mon->vm);
~/libvirt/src/util/virresctrl.c: if (a_type->masks[cache])
virBitmapFree(a_type->masks[cache]);
the check passes succesfully, because the script's logic:
Exit status:
0 one or more matches
1 no match
2 an error
does not play nicely with xargs:
xargs exits with the following status:
0 if it succeeds
123 if any invocation of the command exited with status 1-125
The list of functions is also out of date - e.g. qemuCapsFree has
been renamed since.
This also helps eliminate one more Perl script per our programming
languages strategy:
https://libvirt.org/programming-languages.html
Signed-off-by: Ján Tomko <jtomko(a)redhat.com>
---
build-aux/syntax-check.mk | 190 +-------------------------
build-aux/useless-if-before-free | 226 -------------------------------
2 files changed, 2 insertions(+), 414 deletions(-)
delete mode 100755 build-aux/useless-if-before-free
diff --git a/build-aux/syntax-check.mk b/build-aux/syntax-check.mk
index f493d19dae..b72a5b93d8 100644
--- a/build-aux/syntax-check.mk
+++ b/build-aux/syntax-check.mk
@@ -114,181 +114,6 @@ _test_script_regex = \<test-lib\.sh\>
VC_LIST_ALWAYS_EXCLUDE_REGEX = \
(^(docs/(news(-[0-9]*)?\.html\.in|.*\.patch))|\.(po|fig|gif|ico|png))$$
-# Functions like free() that are no-ops on NULL arguments.
-useless_free_options = \
- --name=VBOX_UTF16_FREE \
- --name=VBOX_UTF8_FREE \
- --name=VBOX_COM_UNALLOC_MEM \
- --name=VIR_FREE \
- --name=qemuCapsFree \
- --name=qemuMigrationCookieFree \
- --name=qemuMigrationCookieGraphicsFree \
- --name=sexpr_free \
- --name=usbFreeDevice \
- --name=virBandwidthDefFree \
- --name=virBitmapFree \
- --name=virCPUDefFree \
- --name=virCapabilitiesFree \
- --name=virCapabilitiesFreeGuest \
- --name=virCapabilitiesFreeGuestDomain \
- --name=virCapabilitiesFreeGuestFeature \
- --name=virCapabilitiesFreeGuestMachine \
- --name=virCapabilitiesFreeHostNUMACell \
- --name=virCapabilitiesFreeMachines \
- --name=virCgroupFree \
- --name=virCommandFree \
- --name=virConfFreeList \
- --name=virConfFreeValue \
- --name=virDomainActualNetDefFree \
- --name=virDomainChrDefFree \
- --name=virDomainControllerDefFree \
- --name=virDomainDefFree \
- --name=virDomainDeviceDefFree \
- --name=virDomainDiskDefFree \
- --name=virDomainEventCallbackListFree \
- --name=virObjectEventQueueFree \
- --name=virDomainFSDefFree \
- --name=virDomainGraphicsDefFree \
- --name=virDomainHostdevDefFree \
- --name=virDomainInputDefFree \
- --name=virDomainNetDefFree \
- --name=virDomainObjFree \
- --name=virDomainSmartcardDefFree \
- --name=virDomainSnapshotObjFree \
- --name=virDomainSoundDefFree \
- --name=virDomainVideoDefFree \
- --name=virDomainWatchdogDefFree \
- --name=virFileDirectFdFree \
- --name=virHashFree \
- --name=virInterfaceDefFree \
- --name=virInterfaceIpDefFree \
- --name=virInterfaceObjFree \
- --name=virInterfaceProtocolDefFree \
- --name=virJSONValueFree \
- --name=virLastErrFreeData \
- --name=virNetMessageFree \
- --name=virNWFilterDefFree \
- --name=virNWFilterEntryFree \
- --name=virNWFilterHashTableFree \
- --name=virNWFilterIPAddrLearnReqFree \
- --name=virNWFilterIncludeDefFree \
- --name=virNWFilterObjFree \
- --name=virNWFilterRuleDefFree \
- --name=virNWFilterRuleInstFree \
- --name=virNetworkDefFree \
- --name=virNodeDeviceDefFree \
- --name=virNodeDeviceObjFree \
- --name=virObjectUnref \
- --name=virObjectFreeCallback \
- --name=virPCIDeviceFree \
- --name=virSecretDefFree \
- --name=virStorageEncryptionFree \
- --name=virStorageEncryptionSecretFree \
- --name=virStorageFileFreeMetadata \
- --name=virStoragePoolDefFree \
- --name=virStoragePoolObjFree \
- --name=virStoragePoolSourceFree \
- --name=virStorageVolDefFree \
- --name=virThreadPoolFree \
- --name=xmlBufferFree \
- --name=xmlFree \
- --name=xmlFreeDoc \
- --name=xmlFreeNode \
- --name=xmlXPathFreeContext \
- --name=xmlXPathFreeObject
-
-# The following template was generated by this command:
-# make ID && aid free|grep '^vi'|sed 's/ .*//;s/^/# /'
-# N virBufferFreeAndReset
-# y virCPUDefFree
-# y virCapabilitiesFree
-# y virCapabilitiesFreeGuest
-# y virCapabilitiesFreeGuestDomain
-# y virCapabilitiesFreeGuestFeature
-# y virCapabilitiesFreeGuestMachine
-# y virCapabilitiesFreeHostNUMACell
-# y virCapabilitiesFreeMachines
-# N virCapabilitiesFreeNUMAInfo FIXME
-# y virCgroupFree
-# N virConfFree (diagnoses the "error")
-# y virConfFreeList
-# y virConfFreeValue
-# y virDomainChrDefFree
-# y virDomainControllerDefFree
-# y virDomainDefFree
-# y virDomainDeviceDefFree
-# y virDomainDiskDefFree
-# y virDomainEventCallbackListFree
-# y virDomainEventQueueFree
-# y virDomainFSDefFree
-# n virDomainFree
-# n virDomainFreeName (can't fix -- returns int)
-# y virDomainGraphicsDefFree
-# y virDomainHostdevDefFree
-# y virDomainInputDefFree
-# y virDomainNetDefFree
-# y virDomainObjFree
-# n virDomainSnapshotFree (returns int)
-# n virDomainSnapshotFreeName (returns int)
-# y virDomainSnapshotObjFree
-# y virDomainSoundDefFree
-# y virDomainVideoDefFree
-# y virDomainWatchdogDefFree
-# n virDrvNodeGetCellsFreeMemory (returns int)
-# n virDrvNodeGetFreeMemory (returns long long)
-# n virFree - dereferences param
-# n virFreeError
-# n virHashFree (takes 2 args)
-# y virInterfaceDefFree
-# n virInterfaceFree (returns int)
-# n virInterfaceFreeName
-# y virInterfaceIpDefFree
-# y virInterfaceObjFree
-# n virInterfaceObjListFree
-# y virInterfaceProtocolDefFree
-# y virJSONValueFree
-# y virLastErrFreeData
-# y virNWFilterDefFree
-# y virNWFilterEntryFree
-# n virNWFilterFree (returns int)
-# y virNWFilterHashTableFree
-# y virNWFilterIPAddrLearnReqFree
-# y virNWFilterIncludeDefFree
-# n virNWFilterFreeName (returns int)
-# y virNWFilterObjFree
-# n virNWFilterObjListFree FIXME
-# y virNWFilterRuleDefFree
-# n virNWFilterRuleFreeInstanceData (typedef)
-# y virNWFilterRuleInstFree
-# y virNetworkDefFree
-# n virNetworkFree (returns int)
-# n virNetworkFreeName (returns int)
-# n virNodeDevCapsDefFree FIXME
-# y virNodeDeviceDefFree
-# n virNodeDeviceFree (returns int)
-# y virNodeDeviceObjFree
-# n virNodeDeviceObjListFree FIXME
-# n virNodeGetCellsFreeMemory (returns int)
-# n virNodeGetFreeMemory (returns non-void)
-# y virSecretDefFree
-# n virSecretFree (returns non-void)
-# n virSecretFreeName (2 args)
-# n virSecurityLabelDefFree FIXME
-# n virStorageBackendDiskMakeFreeExtent (returns non-void)
-# y virStorageEncryptionFree
-# y virStorageEncryptionSecretFree
-# n virStorageFreeType (enum)
-# y virStoragePoolDefFree
-# n virStoragePoolFree (returns non-void)
-# n virStoragePoolFreeName (returns non-void)
-# y virStoragePoolObjFree
-# n virStoragePoolObjListFree FIXME
-# y virStoragePoolSourceFree
-# y virStorageVolDefFree
-# n virStorageVolFree (returns non-void)
-# n virStorageVolFreeName (returns non-void)
-# n virStreamFree
-
# Avoid uses of write(2). Either switch to streams (fwrite), or use
# the safewrite wrapper.
sc_avoid_write:
@@ -1250,17 +1075,6 @@ define _sc_search_regexp
fi || :;
endef
-sc_avoid_if_before_free:
- @$(VC_LIST_EXCEPT) \
- | $(GREP) -v useless-if-before-free \
- | xargs \
- $(top_srcdir)/build-aux/useless-if-before-free \
- $(useless_free_options) \
- && { printf '$(ME): found useless "if"' \
- ' before "free" above\n' 1>&2; \
- exit 1; } \
- || :
-
sc_cast_of_argument_to_free:
@prohibit='\<free *\( *\(' halt="don't cast free argument" \
$(_sc_search_regexp)
@@ -1777,7 +1591,7 @@ exclude_file_name_regexp--sc_prohibit_canonicalize_file_name = \
^(build-aux/syntax-check\.mk|tests/virfilemock\.c)$$
exclude_file_name_regexp--sc_prohibit_raw_allocation = \
-
^(docs/advanced-tests\.rst|src/util/viralloc\.[ch]|examples/.*|tests/(securityselinuxhelper|(vircgroup|nss)mock|commandhelper)\.c|tools/wireshark/src/packet-libvirt\.c|tools/nss/libvirt_nss(_leases|_macs)?\.c|build-aux/useless-if-before-free)$$
+
^(docs/advanced-tests\.rst|src/util/viralloc\.[ch]|examples/.*|tests/(securityselinuxhelper|(vircgroup|nss)mock|commandhelper)\.c|tools/wireshark/src/packet-libvirt\.c|tools/nss/libvirt_nss(_leases|_macs)?\.c)$$
exclude_file_name_regexp--sc_prohibit_readlink = \
^src/(util/virutil|lxc/lxc_container)\.c$$
@@ -1793,7 +1607,7 @@ exclude_file_name_regexp--sc_prohibit_xmlGetProp =
^src/util/virxml\.c$$
exclude_file_name_regexp--sc_prohibit_xmlURI = ^src/util/viruri\.c$$
-exclude_file_name_regexp--sc_prohibit_return_as_function =
\.py|build-aux/useless-if-before-free$$
+exclude_file_name_regexp--sc_prohibit_return_as_function = \.py$$
exclude_file_name_regexp--sc_require_config_h = \
^(examples/|tools/virsh-edit\.c$$|tests/virmockstathelpers.c)
diff --git a/build-aux/useless-if-before-free b/build-aux/useless-if-before-free
deleted file mode 100755
index 6ac8aa9196..0000000000
--- a/build-aux/useless-if-before-free
+++ /dev/null
@@ -1,226 +0,0 @@
-#!/bin/sh
-#! -*-perl-*-
-
-# Detect instances of "if (p) free (p);".
-# Likewise "if (p != 0)", "if (0 != p)", or with NULL; and with
braces.
-
-# Copyright (C) 2008-2019 Free Software Foundation, Inc.
-#
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# This program 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 General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <
https://www.gnu.org/licenses/>.
-#
-# Written by Jim Meyering
-
-# This is a prologue that allows to run a perl script as an executable
-# on systems that are compliant to a POSIX version before POSIX:2017.
-# On such systems, the usual invocation of an executable through execlp()
-# or execvp() fails with ENOEXEC if it is a script that does not start
-# with a #! line. The script interpreter mentioned in the #! line has
-# to be /bin/sh, because on GuixSD systems that is the only program that
-# has a fixed file name. The second line is essential for perl and is
-# also useful for editing this file in Emacs. The next two lines below
-# are valid code in both sh and perl. When executed by sh, they re-execute
-# the script through the perl program found in $PATH. The '-x' option
-# is essential as well; without it, perl would re-execute the script
-# through /bin/sh. When executed by perl, the next two lines are a no-op.
-eval 'exec perl -wSx "$0" "$@"'
- if 0;
-
-my $VERSION = '2018-03-07 03:47'; # UTC
-# The definition above must lie within the first 8 lines in order
-# for the Emacs time-stamp write hook (at end) to update it.
-# If you change this file with Emacs, please let the write hook
-# do its job. Otherwise, update this string manually.
-
-use strict;
-use warnings;
-use Getopt::Long;
-
-(my $ME = $0) =~ s|.*/||;
-
-# use File::Coda; #
https://meyering.net/code/Coda/
-END {
- defined fileno STDOUT or return;
- close STDOUT and return;
- warn "$ME: failed to close standard output: $!\n";
- $? ||= 1;
-}
-
-sub usage ($)
-{
- my ($exit_code) = @_;
- my $STREAM = ($exit_code == 0 ? *STDOUT : *STDERR);
- if ($exit_code != 0)
- {
- print $STREAM "Try '$ME --help' for more information.\n";
- }
- else
- {
- print $STREAM <<EOF;
-Usage: $ME [OPTIONS] FILE...
-
-Detect any instance in FILE of a useless "if" test before a free call, e.g.,
-"if (p) free (p);". Any such test may be safely removed without affecting
-the semantics of the C code in FILE. Use --name=FOO --name=BAR to also
-detect free-like functions named FOO and BAR.
-
-OPTIONS:
-
- --list print only the name of each matching FILE (\\0-terminated)
- --name=N add name N to the list of \'free\'-like functions to detect;
- may be repeated
-
- --help display this help and exit
- --version output version information and exit
-
-Exit status:
-
- 0 one or more matches
- 1 no match
- 2 an error
-
-EXAMPLE:
-
-For example, this command prints all removable "if" tests before
"free"
-and "kfree" calls in the linux kernel sources:
-
- git ls-files -z |xargs -0 $ME --name=kfree
-
-EOF
- }
- exit $exit_code;
-}
-
-sub is_NULL ($)
-{
- my ($expr) = @_;
- return ($expr eq 'NULL' || $expr eq '0');
-}
-
-{
- sub EXIT_MATCH {0}
- sub EXIT_NO_MATCH {1}
- sub EXIT_ERROR {2}
- my $err = EXIT_NO_MATCH;
-
- my $list;
- my @name = qw(free);
- GetOptions
- (
- help => sub { usage 0 },
- version => sub { print "$ME version $VERSION\n"; exit },
- list => \$list,
- 'name=s@' => \@name,
- ) or usage 1;
-
- # Make sure we have the right number of non-option arguments.
- # Always tell the user why we fail.
- @ARGV < 1
- and (warn "$ME: missing FILE argument\n"), usage EXIT_ERROR;
-
- my $or = join '|', @name;
- my $regexp = qr/(?:$or)/;
-
- # Set the input record separator.
- # Note: this makes it impractical to print line numbers.
- $/ = '"';
-
- my $found_match = 0;
- FILE:
- foreach my $file (@ARGV)
- {
- open FH, '<', $file
- or (warn "$ME: can't open '$file' for reading: $!\n"),
- $err = EXIT_ERROR, next;
- while (defined (my $line = <FH>))
- {
- # Skip non-matching lines early to save time
- $line =~ /\bif\b/
- or next;
- while ($line =~
- /\b(if\s*\(\s*([^)]+?)(?:\s*!=\s*([^)]+?))?\s*\)
- # 1 2 3
- (?: \s*$regexp\s*\((?:\s*\([^)]+\))?\s*([^)]+)\)\s*;|
- \s*\{\s*$regexp\s*\((?:\s*\([^)]+\))?\s*([^)]+)\)\s*;\s*\}))/sxg)
- {
- my $all = $1;
- my ($lhs, $rhs) = ($2, $3);
- my ($free_opnd, $braced_free_opnd) = ($4, $5);
- my $non_NULL;
- if (!defined $rhs) { $non_NULL = $lhs }
- elsif (is_NULL $rhs) { $non_NULL = $lhs }
- elsif (is_NULL $lhs) { $non_NULL = $rhs }
- else { next }
-
- # Compare the non-NULL part of the "if" expression and the
- # free'd expression, without regard to white space.
- $non_NULL =~ tr/ \t//d;
- my $e2 = defined $free_opnd ? $free_opnd : $braced_free_opnd;
- $e2 =~ tr/ \t//d;
- if ($non_NULL eq $e2)
- {
- $found_match = 1;
- $list
- and (print "$file\0"), next FILE;
- print "$file: $all\n";
- }
- }
- }
- }
- continue
- {
- close FH;
- }
-
- $found_match && $err == EXIT_NO_MATCH
- and $err = EXIT_MATCH;
-
- exit $err;
-}
-
-my $foo = <<'EOF';
-# The above is to *find* them.
-# This adjusts them, removing the unnecessary "if (p)" part.
-
-# FIXME: do something like this as an option (doesn't do braces):
-free=xfree
-git grep -l -z "$free *(" \
- | xargs -0 useless-if-before-free -l --name="$free" \
- | xargs -0 perl -0x3b -pi -e \
-
's/\bif\s*\(\s*(\S+?)(?:\s*!=\s*(?:0|NULL))?\s*\)\s+('"$free"'\s*\((?:\s*\([^)]+\))?\s*\1\s*\)\s*;)/$2/s'
-
-# Use the following to remove redundant uses of kfree inside braces.
-# Note that -0777 puts perl in slurp-whole-file mode;
-# but we have plenty of memory, these days...
-free=kfree
-git grep -l -z "$free *(" \
- | xargs -0 useless-if-before-free -l --name="$free" \
- | xargs -0 perl -0777 -pi -e \
-
's/\bif\s*\(\s*(\S+?)(?:\s*!=\s*(?:0|NULL))?\s*\)\s*\{\s*('"$free"'\s*\((?:\s*\([^)]+\))?\s*\1\s*\);)\s*\}[^\n]*$/$2/gms'
-
-Be careful that the result of the above transformation is valid.
-If the matched string is followed by "else", then obviously, it won't be.
-
-When modifying files, refuse to process anything other than a regular file.
-EOF
-
-## Local Variables:
-## mode: perl
-## indent-tabs-mode: nil
-## eval: (add-hook 'before-save-hook 'time-stamp)
-## time-stamp-line-limit: 50
-## time-stamp-start: "my $VERSION = '"
-## time-stamp-format: "%:y-%02m-%02d %02H:%02M"
-## time-stamp-time-zone: "UTC0"
-## time-stamp-end: "'; # UTC"
-## End:
--
2.31.1