Pull useless-if-before-free from gnulib, and update.

* bootstrap (gnulib_tool): Add useless-if-before-free to
the list of modules.
* build-aux/useless-if-before-free: Update from gnulib.
* gnulib/lib/vasnprintf.c: Work around a bug in HPUX 10.20.
* gnulib/m4/vasnprintf.m4: Likewise.
This commit is contained in:
Jim Meyering 2008-02-13 21:52:19 +00:00
parent e91aeae437
commit 26709f561f
8 changed files with 140 additions and 39 deletions

View File

@ -1,6 +1,15 @@
Wed Feb 13 22:51:27 CET 2008 Jim Meyering <meyering@redhat.com>
Pull useless-if-before-free from gnulib, and update.
* bootstrap (gnulib_tool): Add useless-if-before-free to
the list of modules.
* build-aux/useless-if-before-free: Update from gnulib.
* gnulib/lib/vasnprintf.c: Work around a bug in HPUX 10.20.
* gnulib/m4/vasnprintf.m4: Likewise.
Tue Feb 12 9:44:22 EST 2008 Daniel P. Berrange <berrange@redhat.com> Tue Feb 12 9:44:22 EST 2008 Daniel P. Berrange <berrange@redhat.com>
* .x-sc_trailing_blank: ignore NEWS / ChangeLog file * .x-sc_trailing_blank: ignore NEWS / ChangeLog file
Mon Feb 11 17:05:53 CET 2008 Daniel Veillard <veillard@redhat.com> Mon Feb 11 17:05:53 CET 2008 Daniel Veillard <veillard@redhat.com>

View File

@ -78,6 +78,7 @@ $gnulib_tool \
--import physmem getaddrinfo \ --import physmem getaddrinfo \
sys_stat vasprintf strndup \ sys_stat vasprintf strndup \
strsep poll gettext getpass \ strsep poll gettext getpass \
useless-if-before-free \
vc-list-files vc-list-files
rm -f \ rm -f \

View File

@ -1,24 +1,43 @@
#!/usr/bin/perl -T #!/usr/bin/perl -T
# Detect instances of "if (p) free (p);". # Detect instances of "if (p) free (p);".
# Likewise for "if (p != NULL) free (p);". # Likewise for "if (p != NULL) free (p);". And with braces.
my $VERSION = '2008-02-04 22:25'; # UTC my $VERSION = '2008-02-11 08:08'; # UTC
# The definition above must lie within the first 8 lines in order # The definition above must lie within the first 8 lines in order
# for the Emacs time-stamp write hook (at end) to update it. # for the Emacs time-stamp write hook (at end) to update it.
# If you change this file with Emacs, please let the write hook # If you change this file with Emacs, please let the write hook
# do its job. Otherwise, update this string manually. # do its job. Otherwise, update this string manually.
# Exit status is like grep: 0 for no match. 1 for any number. # Copyright (C) 2008 Free Software Foundation, Inc.
# Note: giving line numbers isn't practical, since I've reset the
# input record separator. # 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 <http://www.gnu.org/licenses/>.
# Written by Jim Meyering
use strict; use strict;
use warnings; use warnings;
use Getopt::Long; use Getopt::Long;
(my $ME = $0) =~ s|.*/||; (my $ME = $0) =~ s|.*/||;
my $debug = 0; # use File::Coda; # http://meyering.net/code/Coda/
my $verbose = 0; END {
defined fileno STDOUT or return;
close STDOUT and return;
warn "$ME: failed to close standard output: $!\n";
$? ||= 1;
}
sub usage ($) sub usage ($)
{ {
@ -33,18 +52,32 @@ sub usage ($)
print $STREAM <<EOF; print $STREAM <<EOF;
Usage: $ME [OPTIONS] FILE... 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: 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; --name=N add name N to the list of `free'-like functions to detect;
may be repeated may be repeated
--help display this help and exit --help display this help and exit
--version output version information and exit --version output version information and exit
--verbose generate verbose output
Exit status:
0 no match
1 one or more matches
2 an error
EXAMPLE: EXAMPLE:
git ls-files -z |xargs -0 $ME 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 EOF
} }
@ -52,32 +85,40 @@ EOF
} }
{ {
sub EXIT_MATCH {0}
sub EXIT_NO_MATCH {1}
sub EXIT_ERROR {2}
my $err = EXIT_NO_MATCH;
my $list;
my @name = qw(free); my @name = qw(free);
GetOptions GetOptions
( (
debug => \$debug,
verbose => \$verbose,
help => sub { usage 0 }, help => sub { usage 0 },
version => sub { print "$ME version $VERSION\n"; exit }, version => sub { print "$ME version $VERSION\n"; exit },
list => \$list,
'name=s@' => \@name, 'name=s@' => \@name,
) or usage 1; ) or usage 1;
# Make sure we have the right number of non-option arguments. # Make sure we have the right number of non-option arguments.
# Always tell the user why we fail. # Always tell the user why we fail.
@ARGV < 1 @ARGV < 1
and (warn "$ME: missing FILE argument\n"), usage 1; and (warn "$ME: missing FILE argument\n"), usage EXIT_ERROR;
my $or = join '|', @name; my $or = join '|', @name;
my $regexp = qr/(?:$or)/; my $regexp = qr/(?:$or)/;
# Set the input record separator. # Set the input record separator.
# Note: this makes it impractical to print line numbers.
$/ = '"'; $/ = '"';
my $found_match = 0; my $found_match = 0;
FILE:
foreach my $file (@ARGV) foreach my $file (@ARGV)
{ {
open FH, '<', $file open FH, '<', $file
or die "$ME: can't open `$file' for reading: $!\n"; or (warn "$ME: can't open `$file' for reading: $!\n"),
$err = EXIT_ERROR, next;
while (defined (my $line = <FH>)) while (defined (my $line = <FH>))
{ {
if ($line =~ if ($line =~
@ -85,27 +126,40 @@ EOF
(?: \s*$regexp\s*\(\s*\2\s*\)| (?: \s*$regexp\s*\(\s*\2\s*\)|
\s*\{\s*$regexp\s*\(\s*\2\s*\)\s*;\s*\}))/sx) \s*\{\s*$regexp\s*\(\s*\2\s*\)\s*;\s*\}))/sx)
{ {
print "$file: $1\n";
$found_match = 1; $found_match = 1;
$list
and (print "$file\0"), next FILE;
print "$file: $1\n";
} }
} }
}
continue
{
close FH; close FH;
} }
exit !$found_match;
$found_match && $err == EXIT_NO_MATCH
and $err = EXIT_MATCH;
exit $err;
} }
my $foo = <<'EOF'; my $foo = <<'EOF';
# The above is to *find* them. # The above is to *find* them.
# This adjusts them, removing the unnecessary "if (p)" part. # This adjusts them, removing the unnecessary "if (p)" part.
# FIXME: do something like this as an option. # FIXME: do something like this as an option (doesn't do braces):
git ls-files -z --exclude=$ME |xargs -0 \ git ls-files -z |xargs -0 \
perl -0x3b -pi -e 's/\bif\s*\(\s*(\S+?)(?:\s*!=\s*NULL)?\s*\)\s+((?:sexpr_)?free\s*\(\s*\1\s*\))/$2/s' perl -0x3b -pi -e 's/\bif\s*\(\s*(\S+?)(?:\s*!=\s*NULL)?\s*\)\s+(k?free\s*\(\s*\1\s*\))/$2/s'
useless-if-before-free -l $(lid -knone free) | xargs -0 \
perl -0x3b -pi -e \
's/\bif\s*\(\s*(\S+?)(?:\s*!=\s*NULL)?\s*\)\s+(free\s*\(\s*\1\s*\))/$2/s'
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. When modifying files, refuse to process anything other than a regular file.
# Or this one-liner to detect them:
git ls-files -z |xargs -0 perl -00 -ne '/\b(if\s*\(\s*(\S+?)(?:\s*!=\s*NULL)?\s*\)(?:\s*(?:sexpr_)?free\s*\(\s*\2\s*\)|\s*\{\s*(?:sexpr_)?free\s*\(\s*\2\s*\)\s*;\s*\}))/sx and print "$1\n"'
EOF EOF
## Local Variables: ## Local Variables:

View File

@ -9,7 +9,7 @@
# the same distribution terms as the rest of that program. # the same distribution terms as the rest of that program.
# #
# Generated by gnulib-tool. # Generated by gnulib-tool.
# Reproduce by: gnulib-tool --import --dir=. --lib=libgnu --source-base=gnulib/lib --m4-base=gnulib/m4 --doc-base=doc --aux-dir=build-aux --with-tests --lgpl=2 --libtool --macro-prefix=gl getaddrinfo getpass gettext physmem poll strndup strsep sys_stat vasprintf vc-list-files # Reproduce by: gnulib-tool --import --dir=. --lib=libgnu --source-base=gnulib/lib --m4-base=gnulib/m4 --doc-base=doc --aux-dir=build-aux --with-tests --lgpl=2 --libtool --macro-prefix=gl getaddrinfo getpass gettext physmem poll strndup strsep sys_stat useless-if-before-free vasprintf vc-list-files
AUTOMAKE_OPTIONS = 1.5 gnits AUTOMAKE_OPTIONS = 1.5 gnits
@ -701,6 +701,13 @@ EXTRA_DIST += unistd.in.h
## end gnulib module unistd ## end gnulib module unistd
## begin gnulib module useless-if-before-free
EXTRA_DIST += $(top_srcdir)/build-aux/useless-if-before-free
## end gnulib module useless-if-before-free
## begin gnulib module vasnprintf ## begin gnulib module vasnprintf

View File

@ -3566,7 +3566,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
{ {
arg_type type = a.arg[dp->arg_index].type; arg_type type = a.arg[dp->arg_index].type;
int flags = dp->flags; int flags = dp->flags;
#if !USE_SNPRINTF || !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION #if !USE_SNPRINTF || !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_LEFTADJUST || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
int has_width; int has_width;
size_t width; size_t width;
#endif #endif
@ -3579,7 +3579,9 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
#else #else
# define prec_ourselves 0 # define prec_ourselves 0
#endif #endif
#if !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION #if NEED_PRINTF_FLAG_LEFTADJUST
# define pad_ourselves 1
#elif !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
int pad_ourselves; int pad_ourselves;
#else #else
# define pad_ourselves 0 # define pad_ourselves 0
@ -3593,7 +3595,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
TCHAR_T *tmp; TCHAR_T *tmp;
#endif #endif
#if !USE_SNPRINTF || !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION #if !USE_SNPRINTF || !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_LEFTADJUST || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
has_width = 0; has_width = 0;
width = 0; width = 0;
if (dp->width_start != dp->width_end) if (dp->width_start != dp->width_end)
@ -3883,7 +3885,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
#endif #endif
/* Decide whether to perform the padding ourselves. */ /* Decide whether to perform the padding ourselves. */
#if !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION #if !NEED_PRINTF_FLAG_LEFTADJUST && (!DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION)
switch (dp->conversion) switch (dp->conversion)
{ {
# if !DCHAR_IS_TCHAR || ENABLE_UNISTDIO # if !DCHAR_IS_TCHAR || ENABLE_UNISTDIO
@ -4008,7 +4010,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
#endif #endif
*fbp = dp->conversion; *fbp = dp->conversion;
#if USE_SNPRINTF #if USE_SNPRINTF
# if !(__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 3)) # if !(__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 3) || ((defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__))
fbp[1] = '%'; fbp[1] = '%';
fbp[2] = 'n'; fbp[2] = 'n';
fbp[3] = '\0'; fbp[3] = '\0';
@ -4021,6 +4023,21 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
in format strings in writable memory may crash the program in format strings in writable memory may crash the program
(if compiled with _FORTIFY_SOURCE=2), so we should avoid it (if compiled with _FORTIFY_SOURCE=2), so we should avoid it
in this situation. */ in this situation. */
/* On native Win32 systems (such as mingw), we can avoid using
%n because:
- Although the gl_SNPRINTF_TRUNCATION_C99 test fails,
snprintf does not write more than the specified number
of bytes. (snprintf (buf, 3, "%d %d", 4567, 89) writes
'4', '5', '6' into buf, not '4', '5', '\0'.)
- Although the gl_SNPRINTF_RETVAL_C99 test fails, snprintf
allows us to recognize the case of an insufficient
buffer size: it returns -1 in this case.
On native Win32 systems (such as mingw) where the OS is
Windows Vista, the use of %n in format strings by default
crashes the program. See
<http://gcc.gnu.org/ml/gcc/2007-06/msg00122.html> and
<http://msdn2.microsoft.com/en-us/library/ms175782(VS.80).aspx>
So we should avoid %n in this situation. */
fbp[1] = '\0'; fbp[1] = '\0';
# endif # endif
#else #else
@ -4494,7 +4511,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
/* Here count <= allocated - length. */ /* Here count <= allocated - length. */
/* Perform padding. */ /* Perform padding. */
#if !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION #if !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_LEFTADJUST || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
if (pad_ourselves && has_width) if (pad_ourselves && has_width)
{ {
size_t w; size_t w;
@ -4535,15 +4552,14 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
# endif # endif
DCHAR_T *p = rp + count; DCHAR_T *p = rp + count;
DCHAR_T *end = p + pad; DCHAR_T *end = p + pad;
# if NEED_PRINTF_FLAG_ZERO
DCHAR_T *pad_ptr; DCHAR_T *pad_ptr;
# if !DCHAR_IS_TCHAR # if !DCHAR_IS_TCHAR
if (dp->conversion == 'c' if (dp->conversion == 'c'
|| dp->conversion == 's') || dp->conversion == 's')
/* No zero-padding for string directives. */ /* No zero-padding for string directives. */
pad_ptr = NULL; pad_ptr = NULL;
else else
# endif # endif
{ {
pad_ptr = (*rp == '-' ? rp + 1 : rp); pad_ptr = (*rp == '-' ? rp + 1 : rp);
/* No zero-padding of "inf" and "nan". */ /* No zero-padding of "inf" and "nan". */
@ -4551,7 +4567,6 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
|| (*pad_ptr >= 'a' && *pad_ptr <= 'z')) || (*pad_ptr >= 'a' && *pad_ptr <= 'z'))
pad_ptr = NULL; pad_ptr = NULL;
} }
# endif
/* The generated string now extends from rp to p, /* The generated string now extends from rp to p,
with the zero padding insertion point being at with the zero padding insertion point being at
pad_ptr. */ pad_ptr. */
@ -4564,7 +4579,6 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
for (; pad > 0; pad--) for (; pad > 0; pad--)
*p++ = ' '; *p++ = ' ';
} }
# if NEED_PRINTF_FLAG_ZERO
else if ((flags & FLAG_ZERO) && pad_ptr != NULL) else if ((flags & FLAG_ZERO) && pad_ptr != NULL)
{ {
/* Pad with zeroes. */ /* Pad with zeroes. */
@ -4575,7 +4589,6 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
for (; pad > 0; pad--) for (; pad > 0; pad--)
*p++ = '0'; *p++ = '0';
} }
# endif
else else
{ {
/* Pad with spaces on the left. */ /* Pad with spaces on the left. */

View File

@ -15,11 +15,11 @@
# Specification in the form of a command-line invocation: # Specification in the form of a command-line invocation:
# gnulib-tool --import --dir=. --lib=libgnu --source-base=gnulib/lib --m4-base=gnulib/m4 --doc-base=doc --aux-dir=build-aux --with-tests --lgpl=2 --libtool --macro-prefix=gl getaddrinfo getpass gettext physmem poll strndup strsep sys_stat vasprintf vc-list-files # gnulib-tool --import --dir=. --lib=libgnu --source-base=gnulib/lib --m4-base=gnulib/m4 --doc-base=doc --aux-dir=build-aux --with-tests --lgpl=2 --libtool --macro-prefix=gl getaddrinfo getpass gettext physmem poll strndup strsep sys_stat useless-if-before-free vasprintf vc-list-files
# Specification in the form of a few gnulib-tool.m4 macro invocations: # Specification in the form of a few gnulib-tool.m4 macro invocations:
gl_LOCAL_DIR([]) gl_LOCAL_DIR([])
gl_MODULES([getaddrinfo getpass gettext physmem poll strndup strsep sys_stat vasprintf vc-list-files]) gl_MODULES([getaddrinfo getpass gettext physmem poll strndup strsep sys_stat useless-if-before-free vasprintf vc-list-files])
gl_AVOID([]) gl_AVOID([])
gl_SOURCE_BASE([gnulib/lib]) gl_SOURCE_BASE([gnulib/lib])
gl_M4_BASE([gnulib/m4]) gl_M4_BASE([gnulib/m4])

View File

@ -225,6 +225,7 @@ AC_DEFUN([gltests_LIBSOURCES], [
AC_DEFUN([gl_FILE_LIST], [ AC_DEFUN([gl_FILE_LIST], [
build-aux/config.rpath build-aux/config.rpath
build-aux/link-warning.h build-aux/link-warning.h
build-aux/useless-if-before-free
build-aux/vc-list-files build-aux/vc-list-files
lib/alloca.in.h lib/alloca.in.h
lib/asnprintf.c lib/asnprintf.c

View File

@ -1,5 +1,5 @@
# vasnprintf.m4 serial 23 # vasnprintf.m4 serial 24
dnl Copyright (C) 2002-2004, 2006-2007 Free Software Foundation, Inc. dnl Copyright (C) 2002-2004, 2006-2008 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it, dnl gives unlimited permission to copy and/or distribute it,
dnl with or without modifications, as long as this notice is preserved. dnl with or without modifications, as long as this notice is preserved.
@ -166,6 +166,21 @@ AC_DEFUN([gl_PREREQ_VASNPRINTF_FLAG_GROUPING],
esac esac
]) ])
# Extra prerequisites of lib/vasnprintf.c for supporting the '-' flag.
AC_DEFUN([gl_PREREQ_VASNPRINTF_FLAG_LEFTADJUST],
[
AC_REQUIRE([gl_PRINTF_FLAG_LEFTADJUST])
case "$gl_cv_func_printf_flag_leftadjust" in
*yes)
;;
*)
AC_DEFINE([NEED_PRINTF_FLAG_LEFTADJUST], 1,
[Define if the vasnprintf implementation needs special code for the
'-' flag.])
;;
esac
])
# Extra prerequisites of lib/vasnprintf.c for supporting the 0 flag. # Extra prerequisites of lib/vasnprintf.c for supporting the 0 flag.
AC_DEFUN([gl_PREREQ_VASNPRINTF_FLAG_ZERO], AC_DEFUN([gl_PREREQ_VASNPRINTF_FLAG_ZERO],
[ [
@ -234,6 +249,7 @@ AC_DEFUN([gl_PREREQ_VASNPRINTF_WITH_EXTRAS],
gl_PREREQ_VASNPRINTF_DIRECTIVE_A gl_PREREQ_VASNPRINTF_DIRECTIVE_A
gl_PREREQ_VASNPRINTF_DIRECTIVE_F gl_PREREQ_VASNPRINTF_DIRECTIVE_F
gl_PREREQ_VASNPRINTF_FLAG_GROUPING gl_PREREQ_VASNPRINTF_FLAG_GROUPING
gl_PREREQ_VASNPRINTF_FLAG_LEFTADJUST
gl_PREREQ_VASNPRINTF_FLAG_ZERO gl_PREREQ_VASNPRINTF_FLAG_ZERO
gl_PREREQ_VASNPRINTF_PRECISION gl_PREREQ_VASNPRINTF_PRECISION
gl_PREREQ_VASNPRINTF_ENOMEM gl_PREREQ_VASNPRINTF_ENOMEM