[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: bugs in dirname module - coreutils portion
From: |
Eric Blake |
Subject: |
Re: bugs in dirname module - coreutils portion |
Date: |
Wed, 23 Nov 2005 12:21:02 -0700 |
User-agent: |
Mozilla Thunderbird 1.0.2 (Windows/20050317) |
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
This is my patch to coreutils to match the dirname module updates thread
on gnulib: http://lists.gnu.org/archive/html/bug-gnulib/2005-11/msg00071.html
I've also fixed the two nits that Paul had with the latest version of my
gnulib patch, mentioned in
http://lists.gnu.org/archive/html/bug-gnulib/2005-11/msg00076.html.
ChangeLog:
2005-11-23 Eric Blake <address@hidden>
* tests/dirname/basic: New file.
* tests/dirname/Makefile.am: New file.
* tests/basename/basic: Add some tests.
* tests/Makefile.am (SUBDIRS): Add dirname tests.
* configure.ac (AC_CONFIG_FILES): Likewise.
Improvements to dirname/basename handling on platforms like
cygwin with distinct // and with drive letters.
* src/basename.c (main): Don't strip suffix from file system
roots.
* src/cp.c (target_directory_operand): Use new last_component.
(ASSIGN_BASENAME_STRDUPA): Likewise. Reduce time spent
traversing the string.
* src/dircolors.c (guess_shell_syntax): Use new last_component.
* src/install.c (target_directory_operand, install_file_in_dir):
Likewise.
* src/ln.c (target_directory_operand, main): Likewise.
* src/ls.c (basename_is_dot_or_dotdot): Likewise.
* src/mv.c (target_directory_operand, movefile): Likewise.
* src/remove.c (rm_1): Likewise.
* src/rm.c (usage): Clean up after base_name.
* src/shred.c (wipename): Use new last_component.
* src/split.c (next_file_name): Likewise.
* src/su.c (log_su, run_shell): Likewise.
doc/ChangeLog:
2005-11-23 Eric Blake <address@hidden>
* coreutils.texi (basename invocation, dirname invocation):
Improve documentation to match recent patches.
(paste invocation): Fix whitespace.
lib/ChangeLog: (merge from gnulib)
2005-11-22 Eric Blake <address@hidden>
* backupfile.c (check_extension, numbered_backup): Adjust to
changed semantics in dirname module.
* filenamecat.c (file_name_concat): Ditto.
* same.c (same_name): Ditto.
2005-11-22 Eric Blake <address@hidden>,
Paul Eggert <address@hidden>
* dirname.h (FILE_SYSTEM_PREFIX_LEN): Move here from dos.m4.
[FILE_SYSTEM_ACCEPTS_DRIVE_LETTER_PREFIX]: Don't treat 1: as a
drive prefix.
(IS_ABSOLUTE_FILE_NAME): Treat all drive letters as absolute on
platforms like cygwin with FILE_SYSTEM_DRIVE_PREFIX_IS_ABSOLUTE.
(last_component): New method.
* dirname.c (dir_len): Determine when drive letters need a
subsequent slash. Preserve // when it is special.
(dir_name): Don't append dot when drive letter is absolute.
[TEST_DIRNAME]: Move into a full-blown gnulib test.
* basename.c (base_name): New semantics - malloc the result.
Preserve // when it is special. Preserve relative files that look
like drive letters.
(base_len): Preserve // when it is special.
(last_component): New method, similar to old base_name semantics.
* stripslash.c (strip_trailing_slashes): Use last_component, not
base_name. Strip redundant slashes from ///.
m4/ChangeLog: (merge from gnulib)
2005-11-22 Eric Blake <address@hidden>
* dirname.m4 (DOUBLE_SLASH_IS_DISTINCT_ROOT): New define.
* dos.m4 (FILE_SYSTEM_PREFIX_LEN): Move from here to dirname.h.
(FILE_SYSTEM_DRIVE_PREFIX_CAN_BE_RELATIVE): New define.
- --
Life is short - so eat dessert first!
Eric Blake address@hidden
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.1 (Cygwin)
Comment: Public key at home.comcast.net/~ericblake/eblake.gpg
Comment: Using GnuPG with Thunderbird - http://enigmail.mozdev.org
iD8DBQFDhMEd84KuGfSFAYARAnQ4AJ4qwtTTy0p5DhfyDDkyoL9VuFnC8QCguDMo
5R+9bPAaEkv3a0YF2lmlM5I=
=9jCf
-----END PGP SIGNATURE-----
Index: configure.ac
===================================================================
RCS file: /cvsroot/coreutils/coreutils/configure.ac,v
retrieving revision 1.74
diff -u -p -r1.74 configure.ac
--- configure.ac 22 Nov 2005 15:32:20 -0000 1.74
+++ configure.ac 23 Nov 2005 18:43:43 -0000
@@ -235,7 +235,7 @@ if test $jm_cv_sys_tiocgwinsz_needs_term
test $su_cv_sys_tiocgwinsz_in_sys_pty_h = yes \
&& AC_DEFINE(GWINSZ_IN_SYS_PTY, 1,
- [Define if your system defines TIOCGWINSZ in sys/pty.h.])
+ [Define if your system defines TIOCGWINSZ in sys/pty.h.])
fi
# For src/kill.c.
@@ -267,6 +267,7 @@ AC_CONFIG_FILES(
tests/cut/Makefile
tests/dd/Makefile
tests/dircolors/Makefile
+ tests/dirname/Makefile
tests/du/Makefile
tests/expr/Makefile
tests/factor/Makefile
Index: tests/dirname/Makefile.am
===================================================================
RCS file: tests/dirname/Makefile.am
diff -N tests/dirname/Makefile.am
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ tests/dirname/Makefile.am 23 Nov 2005 18:43:43 -0000
@@ -0,0 +1,11 @@
+## Process this file with automake to produce Makefile.in -*-Makefile-*-.
+AUTOMAKE_OPTIONS = 1.4 gnits
+
+TESTS = basic
+EXTRA_DIST = $(TESTS)
+TESTS_ENVIRONMENT = \
+ top_srcdir=$(top_srcdir) \
+ srcdir=$(srcdir) \
+ PERL="$(PERL)" \
+ PATH="`pwd`/../../src$(PATH_SEPARATOR)$$PATH" \
+ PROG=dirname
Index: tests/dirname/basic
===================================================================
RCS file: tests/dirname/basic
diff -N tests/dirname/basic
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ tests/dirname/basic 23 Nov 2005 18:43:43 -0000
@@ -0,0 +1,71 @@
+#!/bin/sh
+# -*-perl-*-
+
+: ${PERL=perl}
+: ${srcdir=.}
+
+$PERL -e 1 > /dev/null 2>&1 || {
+ echo 1>&2 "$0: configure didn't find a usable version of Perl," \
+ "so can't run this test"
+ exit 77
+}
+
+d=$srcdir/..
+exec $PERL -w -I$d -MCoreutils -- - << \EOF
+require 5.003;
+use strict;
+use File::stat;
+
+(my $program_name = $0) =~ s|.*/||;
+
+# Turn off localisation of executable's ouput.
address@hidden(LANGUAGE LANG LC_ALL)} = ('C') x 3;
+
+my $stat_single = stat('/');
+my $stat_double = stat('//');
+my $double_slash = ($stat_single->dev == $stat_double->dev
+ && $stat_single->ino == $stat_double->ino) ? '/' : '//';
+
+my $prog = $ENV{PROG} || die "$0: \$PROG not specified in environment\n";
+
+my @Tests =
+ (
+ ['fail-1', {ERR => "$prog: missing operand\n"
+ . "Try `$prog --help' for more information.\n"}, {EXIT => '1'}],
+ ['fail-2', qw(a b), {ERR => "$prog: extra operand `b'\n"
+ . "Try `$prog --help' for more information.\n"}, {EXIT => '1'}],
+
+ ['a', qw(d/f), {OUT => 'd'}],
+ ['b', qw(/d/f), {OUT => '/d'}],
+ ['c', qw(d/f/), {OUT => 'd'}],
+ ['d', qw(d/f//), {OUT => 'd'}],
+ ['e', qw(f), {OUT => '.'}],
+ ['f', qw(/), {OUT => '/'}],
+ ['g', qw(//), {OUT => "$double_slash"}],
+ ['h', qw(///), {OUT => '/'}],
+ ['i', qw(//a//), {OUT => "$double_slash"}],
+ ['j', qw(///a///), {OUT => '/'}],
+ ['k', qw(///a///b), {OUT => '///a'}],
+ ['l', qw(///a//b/), {OUT => '///a'}],
+ ['m', qw(''), {OUT => '.'}],
+ );
+
+# Append a newline to end of each expected `OUT' string.
+my $t;
+foreach $t (@Tests)
+ {
+ my $arg1 = $t->[1];
+ my $e;
+ foreach $e (@$t)
+ {
+ $e->{OUT} = "$e->{OUT}\n"
+ if ref $e eq 'HASH' and exists $e->{OUT};
+ }
+ }
+
+my $save_temps = $ENV{SAVE_TEMPS};
+my $verbose = $ENV{VERBOSE};
+
+my $fail = run_tests ($program_name, $prog, address@hidden, $save_temps,
$verbose);
+exit $fail;
+EOF
Index: doc/coreutils.texi
===================================================================
RCS file: /cvsroot/coreutils/coreutils/doc/coreutils.texi,v
retrieving revision 1.296
diff -u -p -r1.296 coreutils.texi
--- doc/coreutils.texi 16 Nov 2005 22:45:12 -0000 1.296
+++ doc/coreutils.texi 23 Nov 2005 18:43:46 -0000
@@ -4636,7 +4636,7 @@ c
$ paste num2 let3
1 a
2 b
- c
+ @ c
@end example
Synopsis:
@@ -10394,8 +10394,21 @@ basename @var{name} address@hidden
@end example
If @var{suffix} is specified and is identical to the end of @var{name},
-it is removed from @var{name} as well. @command{basename} prints the
-result on standard output.
+it is removed from @var{name} as well. Note that since trailing slashes
+are removed prior to suffix matching, @var{suffix} will do nothing if it
+contains slashes. @command{basename} prints the result on standard
+output.
+
+Together, @command{basename} and @command{dirname} are designed such
+that if @samp{ls "$name"} succeeds, then the command sequence @samp{cd
+"$(dirname "$name")"; ls "$(basename "$name")"} will too. This works
+for everything except filenames containing a trailing newline.
+
address@hidden allows the implementation to define the results if
address@hidden is empty or @samp{//}. In the former case, @acronym{GNU}
address@hidden returns the empty string. In the latter case, the
+result is @samp{//} on platforms where @var{//} is distinct from
address@hidden/}, and @samp{/} on platforms where there is no difference.
The only options are @option{--help} and @option{--version}. @xref{Common
options}. Options must precede operands.
@@ -10430,6 +10443,16 @@ dirname @var{name}
If @var{name} is a single component, @command{dirname} prints @samp{.}
(meaning the current directory).
+
+Together, @command{basename} and @command{dirname} are designed such
+that if @samp{ls "$name"} succeeds, then the command sequence @samp{cd
+"$(dirname "$name")"; ls "$(basename "$name")"} will too. This works
+for everything except filenames containing a trailing newline.
+
address@hidden allows the implementation to define the results if
address@hidden is @samp{//}. With @acronym{GNU} @command{dirname}, the
+result is @samp{//} on platforms where @var{//} is distinct from
address@hidden/}, and @samp{/} on platforms where there is no difference.
The only options are @option{--help} and @option{--version}. @xref{Common
options}.
Index: lib/backupfile.c
===================================================================
RCS file: /cvsroot/coreutils/coreutils/lib/backupfile.c,v
retrieving revision 1.49
diff -u -p -r1.49 backupfile.c
--- lib/backupfile.c 22 Sep 2005 06:05:39 -0000 1.49
+++ lib/backupfile.c 23 Nov 2005 18:43:48 -0000
@@ -115,7 +115,7 @@ char const *simple_backup_suffix = "~";
static void
check_extension (char *file, size_t filelen, char e)
{
- char *base = base_name (file);
+ char *base = last_component (file);
size_t baselen = base_len (base);
size_t baselen_max = HAVE_LONG_FILE_NAMES ? 255 : NAME_MAX_MINIMUM;
@@ -202,7 +202,7 @@ numbered_backup (char **buffer, size_t b
struct dirent *dp;
char *buf = *buffer;
size_t versionlenmax = 1;
- char *base = base_name (buf);
+ char *base = last_component (buf);
size_t base_offset = base - buf;
size_t baselen = base_len (base);
Index: lib/basename.c
===================================================================
RCS file: /cvsroot/coreutils/coreutils/lib/basename.c,v
retrieving revision 1.26
diff -u -p -r1.26 basename.c
--- lib/basename.c 22 Sep 2005 06:05:39 -0000 1.26
+++ lib/basename.c 23 Nov 2005 18:43:48 -0000
@@ -22,58 +22,107 @@
#endif
#include "dirname.h"
+
#include <string.h>
+#include "xalloc.h"
+#include "xstrndup.h"
+
+/* Return the address of the last file name component of NAME. If
+ NAME has no relative file name components because it is a file
+ system root, return the empty string. */
+
+char *
+last_component (char const *name)
+{
+ char const *base = name + FILE_SYSTEM_PREFIX_LEN (name);
+ char const *p;
+ bool saw_slash = false;
+
+ while (ISSLASH (*base))
+ base++;
+ for (p = base; *p; p++)
+ if (ISSLASH (*p))
+ saw_slash = true;
+ else if (saw_slash)
+ {
+ base = p;
+ saw_slash = false;
+ }
+
+ return (char *) base;
+}
+
/* In general, we can't use the builtin `basename' function if available,
since it has different meanings in different environments.
In some environments the builtin `basename' modifies its argument.
- Return the address of the last file name component of NAME. If
- NAME has no file name components because it is all slashes, return
- NAME if it is empty, the address of its last slash otherwise. */
+ Return the last file name component of NAME, allocated with
+ xmalloc. On systems with drive letters, a leading "./"
+ distinguishes relative names that would otherwise look like a drive
+ letter. Unlike POSIX basename(), NAME cannot be NULL,
+ base_name("") returns "", and the first trailing slash is not
+ stripped.
+
+ If lstat (NAME) would succeed, then { chdir (dir_name (NAME));
+ lstat (base_name (NAME)); } will access the same file. Likewise,
+ if the sequence { chdir (dir_name (NAME));
+ rename (base_name (NAME), "foo"); } succeeds, you have renamed NAME
+ to "foo" in the same directory NAME was in. */
char *
base_name (char const *name)
{
- char const *base = name + FILE_SYSTEM_PREFIX_LEN (name);
- char const *p;
+ char const *base = last_component (name);
+ size_t length;
- for (p = base; *p; p++)
+ /* If there is no last component, then name is a file system root or the
+ empty string. */
+ if (! *base)
+ return xstrndup (name, base_len (name));
+
+ /* Collapse a sequence of trailing slashes into one. */
+ length = base_len (base);
+ if (ISSLASH (base[length]))
+ length++;
+
+ /* On systems with drive letters, `a/b:c' must return `./b:c' rather
+ than `b:c' to avoid confusion with a drive letter. On systems
+ with pure POSIX semantics, this is not an issue. */
+ if (FILE_SYSTEM_PREFIX_LEN (base))
{
- if (ISSLASH (*p))
- {
- /* Treat multiple adjacent slashes like a single slash. */
- do p++;
- while (ISSLASH (*p));
-
- /* If the file name ends in slash, use the trailing slash as
- the basename if no non-slashes have been found. */
- if (! *p)
- {
- if (ISSLASH (*base))
- base = p - 1;
- break;
- }
-
- /* *P is a non-slash preceded by a slash. */
- base = p;
- }
+ char *p = xmalloc (length + 3);
+ p[0] = '.';
+ p[1] = '/';
+ memcpy (p + 2, base, length);
+ p[length + 2] = '\0';
+ return p;
}
- return (char *) base;
+ /* Finally, copy the basename. */
+ return xstrndup (base, length);
}
-/* Return the length of of the basename NAME. Typically NAME is the
- value returned by base_name. Act like strlen (NAME), except omit
- redundant trailing slashes. */
+/* Return the length of the basename NAME. Typically NAME is the
+ value returned by base_name or last_component. Act like strlen
+ (NAME), except omit all trailing slashes. */
size_t
base_len (char const *name)
{
size_t len;
+ size_t prefix_len = FILE_SYSTEM_PREFIX_LEN (name);
for (len = strlen (name); 1 < len && ISSLASH (name[len - 1]); len--)
continue;
+
+ if (DOUBLE_SLASH_IS_DISTINCT_ROOT && len == 1
+ && ISSLASH (name[0]) && ISSLASH (name[1]) && ! name[2])
+ return 2;
+
+ if (FILE_SYSTEM_DRIVE_PREFIX_CAN_BE_RELATIVE && prefix_len
+ && len == prefix_len && ISSLASH (name[prefix_len]))
+ return prefix_len + 1;
return len;
}
Index: lib/dirname.c
===================================================================
RCS file: /cvsroot/coreutils/coreutils/lib/dirname.c,v
retrieving revision 1.36
diff -u -p -r1.36 dirname.c
--- lib/dirname.c 22 Sep 2005 06:05:39 -0000 1.36
+++ lib/dirname.c 23 Nov 2005 18:43:48 -0000
@@ -26,96 +26,62 @@
#include <string.h>
#include "xalloc.h"
-/* Return the length of `dirname (FILE)', or zero if FILE is
- in the working directory. Works properly even if
- there are trailing slashes (by effectively ignoring them). */
+/* Return the length of the prefix of FILE that will be used by
+ dir_name. If FILE is in the working directory, this returns zero
+ even though `dir_name (FILE)' will return ".". Works properly even
+ if there are trailing slashes (by effectively ignoring them). */
+
size_t
dir_len (char const *file)
{
size_t prefix_length = FILE_SYSTEM_PREFIX_LEN (file);
size_t length;
+ /* Advance prefix_length beyond important leading slashes. */
+ prefix_length += (prefix_length != 0
+ ? (FILE_SYSTEM_DRIVE_PREFIX_CAN_BE_RELATIVE
+ && ISSLASH (file[prefix_length]))
+ : (ISSLASH (file[0])
+ ? ((DOUBLE_SLASH_IS_DISTINCT_ROOT
+ && ISSLASH (file[1]) && ! ISSLASH (file[2])
+ ? 2 : 1))
+ : 0));
+
/* Strip the basename and any redundant slashes before it. */
- for (length = base_name (file) - file; prefix_length < length; length--)
+ for (length = last_component (file) - file;
+ prefix_length < length; length--)
if (! ISSLASH (file[length - 1]))
- return length;
-
- /* But don't strip the only slash from "/". */
- return prefix_length + ISSLASH (file[prefix_length]);
+ break;
+ return length;
}
-/* Return the leading directories part of FILE,
- allocated with xmalloc.
- Works properly even if there are trailing slashes
- (by effectively ignoring them). */
+
+/* In general, we can't use the builtin `dirname' function if available,
+ since it has different meanings in different environments.
+ In some environments the builtin `dirname' modifies its argument.
+
+ Return the leading directories part of FILE, allocated with xmalloc.
+ Works properly even if there are trailing slashes (by effectively
+ ignoring them). Unlike POSIX dirname(), FILE cannot be NULL.
+
+ If lstat (FILE) would succeed, then { chdir (dir_name (FILE));
+ lstat (base_name (FILE)); } will access the same file. Likewise,
+ if the sequence { chdir (dir_name (FILE));
+ rename (base_name (FILE), "foo"); } succeeds, you have renamed FILE
+ to "foo" in the same directory FILE was in. */
char *
dir_name (char const *file)
{
size_t length = dir_len (file);
- bool append_dot = (length == FILE_SYSTEM_PREFIX_LEN (file));
+ bool append_dot = (length == 0
+ || (FILE_SYSTEM_DRIVE_PREFIX_CAN_BE_RELATIVE
+ && length == FILE_SYSTEM_PREFIX_LEN (file)
+ && file[2] != '\0' && ! ISSLASH (file[2])));
char *dir = xmalloc (length + append_dot + 1);
memcpy (dir, file, length);
if (append_dot)
dir[length++] = '.';
- dir[length] = 0;
+ dir[length] = '\0';
return dir;
}
-
-#ifdef TEST_DIRNAME
-/*
-
-Run the test like this (expect no output):
- gcc -DHAVE_CONFIG_H -DTEST_DIRNAME -I.. -O -Wall \
- basename.c dirname.c xmalloc.c error.c
- sed -n '/^BEGIN-DATA$/,/^END-DATA$/p' dirname.c|grep -v DATA|./a.out
-
-If it's been built on a DOS or Windows platforms, run another test like
-this (again, expect no output):
- sed -n '/^BEGIN-DOS-DATA$/,/^END-DOS-DATA$/p' dirname.c|grep -v DATA|./a.out
-
-BEGIN-DATA
-foo//// .
-bar/foo//// bar
-foo/ .
-/ /
-. .
-a .
-END-DATA
-
-BEGIN-DOS-DATA
-c:///// c:/
-c:/ c:/
-c:/. c:/
-c:foo c:.
-c:foo/bar c:foo
-END-DOS-DATA
-
-*/
-
-# define MAX_BUFF_LEN 1024
-# include <stdio.h>
-
-char *program_name;
-
-int
-main (int argc, char *argv[])
-{
- char buff[MAX_BUFF_LEN + 1];
-
- program_name = argv[0];
-
- buff[MAX_BUFF_LEN] = 0;
- while (fgets (buff, MAX_BUFF_LEN, stdin) && buff[0])
- {
- char file[MAX_BUFF_LEN];
- char expected_result[MAX_BUFF_LEN];
- char const *result;
- sscanf (buff, "%s %s", file, expected_result);
- result = dir_name (file);
- if (strcmp (result, expected_result))
- printf ("%s: got %s, expected %s\n", file, result, expected_result);
- }
- return 0;
-}
-#endif
Index: lib/dirname.h
===================================================================
RCS file: /cvsroot/coreutils/coreutils/lib/dirname.h,v
retrieving revision 1.15
diff -u -p -r1.15 dirname.h
--- lib/dirname.h 2 Jun 2005 05:05:29 -0000 1.15
+++ lib/dirname.h 23 Nov 2005 18:43:48 -0000
@@ -31,16 +31,39 @@
# endif
# ifndef FILE_SYSTEM_PREFIX_LEN
-# define FILE_SYSTEM_PREFIX_LEN(File_name) 0
+# if FILE_SYSTEM_ACCEPTS_DRIVE_LETTER_PREFIX
+ /* This internal macro assumes ASCII, but all hosts that support drive
+ letters use ASCII. */
+# define _IS_DRIVE_LETTER(c) (((unsigned int) (c) | ('a' - 'A')) - 'a' \
+ <= 'z' - 'a')
+# define FILE_SYSTEM_PREFIX_LEN(Filename) \
+ (_IS_DRIVE_LETTER ((Filename)[0]) && (Filename)[1] == ':' ? 2 : 0)
+# else
+# define FILE_SYSTEM_PREFIX_LEN(Filename) 0
+# endif
# endif
-# define IS_ABSOLUTE_FILE_NAME(F) ISSLASH ((F)[FILE_SYSTEM_PREFIX_LEN (F)])
+# ifndef FILE_SYSTEM_DRIVE_PREFIX_CAN_BE_RELATIVE
+# define FILE_SYSTEM_DRIVE_PREFIX_CAN_BE_RELATIVE 0
+# endif
+
+# ifndef DOUBLE_SLASH_IS_DISTINCT_ROOT
+# define DOUBLE_SLASH_IS_DISTINCT_ROOT 1
+# endif
+
+# if FILE_SYSTEM_DRIVE_PREFIX_CAN_BE_RELATIVE
+# define IS_ABSOLUTE_FILE_NAME(F) ISSLASH ((F)[FILE_SYSTEM_PREFIX_LEN (F)])
+# else
+# define IS_ABSOLUTE_FILE_NAME(F) \
+ (ISSLASH ((F)[0]) || 0 < FILE_SYSTEM_PREFIX_LEN (F))
+# endif
# define IS_RELATIVE_FILE_NAME(F) (! IS_ABSOLUTE_FILE_NAME (F))
char *base_name (char const *file);
char *dir_name (char const *file);
size_t base_len (char const *file);
size_t dir_len (char const *file);
+char *last_component (char const *file);
bool strip_trailing_slashes (char *file);
Index: lib/filenamecat.c
===================================================================
RCS file: /cvsroot/coreutils/coreutils/lib/filenamecat.c,v
retrieving revision 1.2
diff -u -p -r1.2 filenamecat.c
--- lib/filenamecat.c 22 Sep 2005 06:05:39 -0000 1.2
+++ lib/filenamecat.c 23 Nov 2005 18:43:48 -0000
@@ -64,7 +64,7 @@ longest_relative_suffix (char const *f)
char *
file_name_concat (char const *dir, char const *abase, char **base_in_result)
{
- char const *dirbase = base_name (dir);
+ char const *dirbase = last_component (dir);
size_t dirbaselen = base_len (dirbase);
size_t dirlen = dirbase - dir + dirbaselen;
size_t needs_separator = (dirbaselen && ! ISSLASH (dirbase[dirbaselen - 1]));
Index: lib/same.c
===================================================================
RCS file: /cvsroot/coreutils/coreutils/lib/same.c,v
retrieving revision 1.18
diff -u -p -r1.18 same.c
--- lib/same.c 22 Sep 2005 06:05:39 -0000 1.18
+++ lib/same.c 23 Nov 2005 18:43:48 -0000
@@ -59,8 +59,8 @@ bool
same_name (const char *source, const char *dest)
{
/* Compare the basenames. */
- char const *source_basename = base_name (source);
- char const *dest_basename = base_name (dest);
+ char const *source_basename = last_component (source);
+ char const *dest_basename = last_component (dest);
size_t source_baselen = base_len (source_basename);
size_t dest_baselen = base_len (dest_basename);
bool identical_basenames =
Index: lib/stripslash.c
===================================================================
RCS file: /cvsroot/coreutils/coreutils/lib/stripslash.c,v
retrieving revision 1.15
diff -u -p -r1.15 stripslash.c
--- lib/stripslash.c 22 Sep 2005 06:05:39 -0000 1.15
+++ lib/stripslash.c 23 Nov 2005 18:43:48 -0000
@@ -22,19 +22,26 @@
#include "dirname.h"
-/* Remove trailing slashes from FILE.
- Return true if a trailing slash was removed.
- This is useful when using file name completion from a shell that
- adds a "/" after directory names (such as tcsh and bash), because
- the Unix rename and rmdir system calls return an "Invalid argument" error
- when given a file that ends in "/" (except for the root directory). */
+/* Remove trailing slashes from FILE. Return true if a trailing slash
+ was removed. This is useful when using file name completion from a
+ shell that adds a "/" after directory names (such as tcsh and
+ bash), because on symlinks to directories, several system calls
+ have different semantics according to whether a trailing slash is
+ present. */
bool
strip_trailing_slashes (char *file)
{
- char *base = base_name (file);
- char *base_lim = base + base_len (base);
- bool had_slash = (*base_lim != '\0');
+ char *base = last_component (file);
+ char *base_lim;
+ bool had_slash;
+
+ /* last_component returns "" for file system roots, but we need to turn
+ `///' into `/'. */
+ if (! *base)
+ base = file;
+ base_lim = base + base_len (base);
+ had_slash = (*base_lim != '\0');
*base_lim = '\0';
return had_slash;
}
Index: m4/ChangeLog
===================================================================
RCS file: /cvsroot/coreutils/coreutils/m4/ChangeLog,v
retrieving revision 1.766
diff -u -p -r1.766 ChangeLog
Index: m4/dirname.m4
===================================================================
RCS file: /cvsroot/coreutils/coreutils/m4/dirname.m4,v
retrieving revision 1.7
diff -u -p -r1.7 dirname.m4
--- m4/dirname.m4 29 Jan 2005 00:16:39 -0000 1.7
+++ m4/dirname.m4 23 Nov 2005 18:43:49 -0000
@@ -1,4 +1,4 @@
-# dirname.m4 serial 5
+# dirname.m4 serial 6
dnl Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
@@ -11,6 +11,28 @@ AC_DEFUN([gl_DIRNAME],
dnl Prerequisites of lib/dirname.h.
AC_REQUIRE([gl_AC_DOS])
+ AC_CACHE_CHECK([whether // is distinct from /], [ac_cv_double_slash_root],
+ [ if test x"$cross_compiling" = xyes ; then
+ # When cross-compiling, there is no way to tell whether // is special
+ # short of a list of hosts; so always treat it as special.
+ ac_cv_double_slash_root=unknown
+ else
+ set x `ls -di / //`
+ if test $[2] = $[4]; then
+ ac_cv_double_slash_root=no
+ else
+ ac_cv_double_slash_root=yes
+ fi
+ fi])
+ if test x"$ac_cv_double_slash_root" = xno; then
+ ac_double_slash_root=0
+ else
+ ac_double_slash_root=1
+ fi
+
+ AC_DEFINE_UNQUOTED([DOUBLE_SLASH_IS_DISTINCT_ROOT],
+ $ac_double_slash_root,
+ [Define to 1 if // is a file system root distinct from /.])
dnl No prerequisites of lib/basename.c, lib/dirname.c, lib/stripslash.c.
])
Index: m4/dos.m4
===================================================================
RCS file: /cvsroot/coreutils/coreutils/m4/dos.m4,v
retrieving revision 1.13
diff -u -p -r1.13 dos.m4
--- m4/dos.m4 23 Jan 2005 09:07:57 -0000 1.13
+++ m4/dos.m4 23 Nov 2005 18:43:49 -0000
@@ -1,9 +1,9 @@
-#serial 9
+#serial 10
# Define some macros required for proper operation of code in lib/*.c
# on MSDOS/Windows systems.
-# Copyright (C) 2000, 2001, 2004 Free Software Foundation, Inc.
+# Copyright (C) 2000, 2001, 2004, 2005 Free Software Foundation, Inc.
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
@@ -14,30 +14,38 @@ AC_DEFUN([gl_AC_DOS],
[
AC_CACHE_CHECK([whether system is Windows or MSDOS], [ac_cv_win_or_dos],
[
- AC_TRY_COMPILE([],
- [#if !defined _WIN32 && !defined __WIN32__ && !defined __MSDOS__ &&
!defined __CYGWIN__
+ AC_TRY_COMPILE([],
+ [#if !defined _WIN32 && !defined __WIN32__ && !defined __MSDOS__ &&
!defined __CYGWIN__
neither MSDOS nor Windows
#endif],
- [ac_cv_win_or_dos=yes],
- [ac_cv_win_or_dos=no])
+ [ac_cv_win_or_dos=yes],
+ [ac_cv_win_or_dos=no])
])
if test x"$ac_cv_win_or_dos" = xyes; then
ac_fs_accepts_drive_letter_prefix=1
ac_fs_backslash_is_file_name_separator=1
+ AC_CACHE_CHECK([whether drive letter can start relative path],
+ [ac_cv_drive_letter_can_be_relative],
+ [
+ AC_TRY_COMPILE([],
+ [#if defined __CYGWIN__
+drive letters are always absolute
+#endif],
+ [ac_cv_drive_letter_can_be_relative=yes],
+ [ac_cv_drive_letter_can_be_relative=no])
+ ])
+ if test x"$ac_cv_drive_letter_can_be_relative" = xyes; then
+ ac_fs_drive_letter_can_be_relative=1
+ else
+ ac_fs_drive_letter_can_be_relative=0
+ fi
else
ac_fs_accepts_drive_letter_prefix=0
ac_fs_backslash_is_file_name_separator=0
+ ac_fs_drive_letter_can_be_relative=0
fi
- AH_VERBATIM(FILE_SYSTEM_PREFIX_LEN,
- [#if FILE_SYSTEM_ACCEPTS_DRIVE_LETTER_PREFIX
-# define FILE_SYSTEM_PREFIX_LEN(Filename) \
- ((Filename)[0] && (Filename)[1] == ':' ? 2 : 0)
-#else
-# define FILE_SYSTEM_PREFIX_LEN(Filename) 0
-#endif])
-
AC_DEFINE_UNQUOTED([FILE_SYSTEM_ACCEPTS_DRIVE_LETTER_PREFIX],
$ac_fs_accepts_drive_letter_prefix,
[Define on systems for which file names may have a so-called
@@ -55,4 +63,9 @@ neither MSDOS nor Windows
$ac_fs_backslash_is_file_name_separator,
[Define if the backslash character may also serve as a file name
component separator.])
+
+ AC_DEFINE_UNQUOTED([FILE_SYSTEM_DRIVE_PREFIX_CAN_BE_RELATIVE],
+ $ac_fs_drive_letter_can_be_relative,
+ [Define if a drive letter prefix denotes a relative path if it is
+ not followed by a file name component separator.])
])
Index: src/basename.c
===================================================================
RCS file: /cvsroot/coreutils/coreutils/src/basename.c,v
retrieving revision 1.63
diff -u -p -r1.63 basename.c
--- src/basename.c 2 Jun 2005 05:17:24 -0000 1.63
+++ src/basename.c 23 Nov 2005 18:43:49 -0000
@@ -126,12 +126,20 @@ main (int argc, char **argv)
}
name = base_name (argv[optind]);
- name[base_len (name)] = '\0';
+ strip_trailing_slashes (name);
- if (argc == optind + 2)
+ /* Per POSIX, `basename // /' must return `//' on platforms with
+ distinct //. On platforms with drive letters, this generalizes
+ to making `basename c: :' return `c:'. This rule is captured by
+ skipping suffix stripping if base_name returned an absolute path
+ or a drive letter (only possible if name is a file-system
+ root). */
+ if (argc == optind + 2 && IS_RELATIVE_FILE_NAME (name)
+ && ! FILE_SYSTEM_PREFIX_LEN (name))
remove_suffix (name, argv[optind + 1]);
puts (name);
+ free (name);
exit (EXIT_SUCCESS);
}
Index: src/cp.c
===================================================================
RCS file: /cvsroot/coreutils/coreutils/src/cp.c,v
retrieving revision 1.215
diff -u -p -r1.215 cp.c
--- src/cp.c 16 Sep 2005 07:50:33 -0000 1.215
+++ src/cp.c 23 Nov 2005 18:43:49 -0000
@@ -1,5 +1,5 @@
/* cp.c -- file copying (main routines)
- Copyright (C) 89, 90, 91, 1995-2005 Free Software Foundation.
+ Copyright (C) 1989, 1990, 1991, 1995-2005 Free Software Foundation.
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
@@ -41,8 +41,8 @@
{ \
char *tmp_abns_; \
ASSIGN_STRDUPA (tmp_abns_, (File_name)); \
+ Dest = last_component (tmp_abns_); \
strip_trailing_slashes (tmp_abns_); \
- Dest = base_name (tmp_abns_); \
} \
while (0)
@@ -175,7 +175,7 @@ Mandatory arguments to long options are
"), stdout);
fputs (_("\
-f, --force if an existing destination file cannot be\n\
- opened, remove it and try again\n\
+ opened, remove it and try again\n\
-i, --interactive prompt before overwrite\n\
-H follow command-line symbolic links\n\
"), stdout);
@@ -189,8 +189,8 @@ Mandatory arguments to long options are
fputs (_("\
-p same as --preserve=mode,ownership,timestamps\n\
--preserve[=ATTR_LIST] preserve the specified attributes (default:\n\
- mode,ownership,timestamps), if possible\n\
- additional attributes: links, all\n\
+ mode,ownership,timestamps), if possible\n\
+ additional attributes: links, all\n\
"), stdout);
fputs (_("\
--no-preserve=ATTR_LIST don't preserve the specified attributes\n\
@@ -199,12 +199,12 @@ Mandatory arguments to long options are
fputs (_("\
-R, -r, --recursive copy directories recursively\n\
--remove-destination remove each existing destination file before\n\
- attempting to open it (contrast with
--force)\n\
+ attempting to open it (contrast with
--force)\n\
"), stdout);
fputs (_("\
--sparse=WHEN control creation of sparse files\n\
--strip-trailing-slashes remove any trailing slashes from each SOURCE\n\
- argument\n\
+ argument\n\
"), stdout);
fputs (_("\
-s, --symbolic-link make symbolic links instead of copying\n\
@@ -214,8 +214,8 @@ Mandatory arguments to long options are
"), stdout);
fputs (_("\
-u, --update copy only when the SOURCE file is newer\n\
- than the destination file or when the\n\
- destination file is missing\n\
+ than the destination file or when the\n\
+ destination file is missing\n\
-v, --verbose explain what is being done\n\
-x, --one-file-system stay on this file system\n\
"), stdout);
@@ -471,7 +471,7 @@ make_dir_parents_private (char const *co
static bool
target_directory_operand (char const *file, struct stat *st, bool *new_dst)
{
- char const *b = base_name (file);
+ char const *b = last_component (file);
size_t blen = strlen (b);
bool looks_like_a_dir = (blen == 0 || ISSLASH (b[blen - 1]));
int err = (stat (file, st) == 0 ? 0 : errno);
@@ -581,8 +581,8 @@ do_copy (int n_files, char **file, const
&arg_in_concat);
/* For --parents, we have to make sure that the directory
- dir_name (dst_name) exists. We may have to create a few
- leading directories. */
+ dir_name (dst_name) exists. We may have to create a few
+ leading directories. */
parent_exists =
(make_dir_parents_private
(dst_name, arg_in_concat - dst_name, S_IRWXU,
Index: src/dircolors.c
===================================================================
RCS file: /cvsroot/coreutils/coreutils/src/dircolors.c,v
retrieving revision 1.97
diff -u -p -r1.97 dircolors.c
--- src/dircolors.c 24 Oct 2005 10:39:46 -0000 1.97
+++ src/dircolors.c 23 Nov 2005 18:43:49 -0000
@@ -99,7 +99,7 @@ usage (int status)
{
if (status != EXIT_SUCCESS)
fprintf (stderr, _("Try `%s --help' for more information.\n"),
- program_name);
+ program_name);
else
{
printf (_("Usage: %s [OPTION]... [FILE]\n"), program_name);
@@ -137,7 +137,7 @@ guess_shell_syntax (void)
if (shell == NULL || *shell == '\0')
return SHELL_SYNTAX_UNKNOWN;
- shell = base_name (shell);
+ shell = last_component (shell);
if (STREQ (shell, "csh") || STREQ (shell, "tcsh"))
return SHELL_SYNTAX_C;
Index: src/install.c
===================================================================
RCS file: /cvsroot/coreutils/coreutils/src/install.c,v
retrieving revision 1.189
diff -u -p -r1.189 install.c
--- src/install.c 23 Sep 2005 20:50:49 -0000 1.189
+++ src/install.c 23 Nov 2005 18:43:50 -0000
@@ -168,7 +168,7 @@ cp_option_init (struct cp_options *x)
static bool
target_directory_operand (char const *file)
{
- char const *b = base_name (file);
+ char const *b = last_component (file);
size_t blen = strlen (b);
bool looks_like_a_dir = (blen == 0 || ISSLASH (b[blen - 1]));
struct stat st;
@@ -372,8 +372,8 @@ main (int argc, char **argv)
hash_init ();
if (!target_directory)
- {
- if (mkdir_and_install)
+ {
+ if (mkdir_and_install)
ok = install_file_in_file_parents (file[0], file[1], &x);
else
ok = install_file_in_file (file[0], file[1], &x);
@@ -464,7 +464,7 @@ static bool
install_file_in_dir (const char *from, const char *to_dir,
const struct cp_options *x)
{
- const char *from_base = base_name (from);
+ const char *from_base = last_component (from);
char *to = file_name_concat (to_dir, from_base, NULL);
bool ret = install_file_in_file (from, to, x);
free (to);
@@ -651,18 +651,18 @@ Mandatory arguments to long options are
-b like --backup but does not accept an argument\n\
-c (ignored)\n\
-d, --directory treat all arguments as directory names; create all\n\
- components of the specified directories\n\
+ components of the specified directories\n\
"), stdout);
fputs (_("\
-D create all leading components of DEST except the last,\n\
- then copy SOURCE to DEST\n\
+ then copy SOURCE to DEST\n\
-g, --group=GROUP set group ownership, instead of process' current group\n\
-m, --mode=MODE set permission mode (as in chmod), instead of
rwxr-xr-x\n\
-o, --owner=OWNER set ownership (super-user only)\n\
"), stdout);
fputs (_("\
-p, --preserve-timestamps apply access/modification times of SOURCE
files\n\
- to corresponding destination files\n\
+ to corresponding destination files\n\
-s, --strip strip symbol tables\n\
-S, --suffix=SUFFIX override the usual backup suffix\n\
-t, --target-directory=DIRECTORY copy all SOURCE arguments into DIRECTORY\n\
Index: src/ln.c
===================================================================
RCS file: /cvsroot/coreutils/coreutils/src/ln.c,v
retrieving revision 1.155
diff -u -p -r1.155 ln.c
--- src/ln.c 16 Nov 2005 22:32:45 -0000 1.155
+++ src/ln.c 23 Nov 2005 18:43:50 -0000
@@ -113,7 +113,7 @@ static struct option const long_options[
static bool
target_directory_operand (char const *file)
{
- char const *b = base_name (file);
+ char const *b = last_component (file);
size_t blen = strlen (b);
bool looks_like_a_dir = (blen == 0 || ISSLASH (b[blen - 1]));
struct stat st;
@@ -339,20 +339,20 @@ Mandatory arguments to long options are
--backup[=CONTROL] make a backup of each existing destination
file\n\
-b like --backup but does not accept an argument\n\
-d, -F, --directory allow the superuser to attempt to hard link\n\
- directories (note: will probably fail due to\n\
- system restrictions, even for the superuser)\n\
+ directories (note: will probably fail due to\n\
+ system restrictions, even for the superuser)\n\
-f, --force remove existing destination files\n\
"), stdout);
fputs (_("\
-n, --no-dereference treat destination that is a symlink to a\n\
- directory as if it were a normal file\n\
+ directory as if it were a normal file\n\
-i, --interactive prompt whether to remove destinations\n\
-s, --symbolic make symbolic links instead of hard links\n\
"), stdout);
fputs (_("\
-S, --suffix=SUFFIX override the usual backup suffix\n\
-t, --target-directory=DIRECTORY specify the DIRECTORY in which to create\n\
- the links\n\
+ the links\n\
-T, --no-target-directory treat LINK_NAME as a normal file\n\
-v, --verbose print name of each linked file\n\
"), stdout);
@@ -525,7 +525,8 @@ main (int argc, char **argv)
for (i = 0; i < n_files; ++i)
{
char *dest_base;
- char *dest = file_name_concat (target_directory, base_name (file[i]),
+ char *dest = file_name_concat (target_directory,
+ last_component (file[i]),
&dest_base);
strip_trailing_slashes (dest_base);
ok &= do_link (file[i], dest);
Index: src/ls.c
===================================================================
RCS file: /cvsroot/coreutils/coreutils/src/ls.c,v
retrieving revision 1.403
diff -u -p -r1.403 ls.c
--- src/ls.c 17 Nov 2005 12:28:34 -0000 1.403
+++ src/ls.c 23 Nov 2005 18:43:51 -0000
@@ -1157,8 +1157,8 @@ main (int argc, char **argv)
check_symlink_color = true;
/* If the standard output is a controlling terminal, watch out
- for signals, so that the colors can be restored to the
- default state if "ls" is suspended or interrupted. */
+ for signals, so that the colors can be restored to the
+ default state if "ls" is suspended or interrupted. */
if (0 <= tcgetpgrp (STDOUT_FILENO))
{
@@ -1694,9 +1694,9 @@ decode_switches (int argc, char **argv)
format = one_per_line;
break;
- case AUTHOR_OPTION:
- print_author = true;
- break;
+ case AUTHOR_OPTION:
+ print_author = true;
+ break;
case HIDE_OPTION:
{
@@ -2006,7 +2006,7 @@ get_funky_string (char **dest, const cha
num = '\v';
break;
case '?': /* Delete */
- num = 127;
+ num = 127;
break;
case '_': /* Space */
num = ' ';
@@ -2617,8 +2617,8 @@ gobble_file (char const *name, enum file
f->linkok = true;
/* Symbolic links to directories that are mentioned on the
- command line are automatically traced if not being
- listed as files. */
+ command line are automatically traced if not being
+ listed as files. */
if (!command_line_arg || format == long_format
|| !S_ISDIR (linkstats.st_mode))
{
@@ -2779,7 +2779,7 @@ make_link_name (char const *name, char c
static bool
basename_is_dot_or_dotdot (const char *name)
{
- char const *base = base_name (name);
+ char const *base = last_component (name);
return DOT_OR_DOTDOT (base);
}
@@ -4124,16 +4124,16 @@ Mandatory arguments to long options are
--block-size=SIZE use SIZE-byte blocks\n\
-B, --ignore-backups do not list implied entries ending with ~\n\
-c with -lt: sort by, and show, ctime (time of
last\n\
- modification of file status information)\n\
- with -l: show ctime and sort by name\n\
- otherwise: sort by ctime\n\
+ modification of file status information)\n\
+ with -l: show ctime and sort by name\n\
+ otherwise: sort by ctime\n\
"), stdout);
fputs (_("\
-C list entries by columns\n\
--color[=WHEN] control whether color is used to distinguish
file\n\
- types. WHEN may be `never', `always', or
`auto'\n\
+ types. WHEN may be `never', `always', or
`auto'\n\
-d, --directory list directory entries instead of contents,\n\
- and do not dereference symbolic links\n\
+ and do not dereference symbolic links\n\
-D, --dired generate output designed for Emacs' dired mode\n\
"), stdout);
fputs (_("\
@@ -4141,27 +4141,27 @@ Mandatory arguments to long options are
-F, --classify append indicator (one of */=>@|) to entries\n\
--file-type likewise, except do not append `*'\n\
--format=WORD across -x, commas -m, horizontal -x, long -l,\n\
- single-column -1, verbose -l, vertical -C\n\
+ single-column -1, verbose -l, vertical -C\n\
--full-time like -l --time-style=full-iso\n\
"), stdout);
fputs (_("\
-g like -l, but do not list owner\n\
-G, --no-group like -l, but do not list group\n\
-h, --human-readable with -l, print sizes in human readable format\n\
- (e.g., 1K 234M 2G)\n\
+ (e.g., 1K 234M 2G)\n\
--si likewise, but use powers of 1000 not 1024\n\
-H, --dereference-command-line\n\
- follow symbolic links listed on the command
line\n\
+ follow symbolic links listed on the command line\n\
--dereference-command-line-symlink-to-dir\n\
- follow each command line symbolic link\n\
- that points to a directory\n\
+ follow each command line symbolic link\n\
+ that points to a directory\n\
--hide=PATTERN do not list implied entries matching shell
PATTERN\n\
- (overridden by -a or -A)\n\
+ (overridden by -a or -A)\n\
"), stdout);
fputs (_("\
--indicator-style=WORD append indicator with style WORD to entry
names:\n\
- none (default), slash (-p),\n\
- file-type (--file-type), classify (-F)\n\
+ none (default), slash (-p),\n\
+ file-type (--file-type), classify (-F)\n\
-i, --inode with -l, print the index number of each file\n\
-I, --ignore=PATTERN do not list implied entries matching shell
PATTERN\n\
-k like --block-size=1K\n\
@@ -4169,25 +4169,25 @@ Mandatory arguments to long options are
fputs (_("\
-l use a long listing format\n\
-L, --dereference when showing file information for a symbolic\n\
- link, show information for the file the link\n\
- references rather than for the link itself\n\
+ link, show information for the file the link\n\
+ references rather than for the link itself\n\
-m fill width with a comma separated list of
entries\n\
"), stdout);
fputs (_("\
-n, --numeric-uid-gid like -l, but list numeric user and group IDs\n\
-N, --literal print raw entry names (don't treat e.g. control\n\
- characters specially)\n\
+ characters specially)\n\
-o like -l, but do not list group information\n\
-p, --indicator-style=slash\n\
- append / indicator to directories\n\
+ append / indicator to directories\n\
"), stdout);
fputs (_("\
-q, --hide-control-chars print ? instead of non graphic characters\n\
--show-control-chars show non graphic characters as-is (default\n\
- unless program is `ls' and output is a
terminal)\n\
+ unless program is `ls' and output is a terminal)\n\
-Q, --quote-name enclose entry names in double quotes\n\
--quoting-style=WORD use quoting style WORD for entry names:\n\
- literal, locale, shell, shell-always, c,
escape\n\
+ literal, locale, shell, shell-always, c,
escape\n\
"), stdout);
fputs (_("\
-r, --reverse reverse order while sorting\n\
@@ -4197,27 +4197,27 @@ Mandatory arguments to long options are
fputs (_("\
-S sort by file size\n\
--sort=WORD sort by WORD instead of name: none -U,\n\
- extension -X, size -S, time -t, version -v\n\
+ extension -X, size -S, time -t, version -v\n\
--time=WORD with -l, show time as WORD instead of
modification\n\
- time: atime -u, access -u, use -u, ctime -c,\n\
- or status -c; use specified time as sort key\n\
- if --sort=time\n\
+ time: atime -u, access -u, use -u, ctime -c,\n\
+ or status -c; use specified time as sort key\n\
+ if --sort=time\n\
"), stdout);
fputs (_("\
--time-style=STYLE with -l, show times using style STYLE:\n\
- full-iso, long-iso, iso, locale, +FORMAT.\n\
- FORMAT is interpreted like `date'; if FORMAT is\n\
- FORMAT1<newline>FORMAT2, FORMAT1 applies to\n\
- non-recent files and FORMAT2 to recent files;\n\
- if STYLE is prefixed with `posix-', STYLE\n\
- takes effect only outside the POSIX locale\n\
+ full-iso, long-iso, iso, locale, +FORMAT.\n\
+ FORMAT is interpreted like `date'; if FORMAT is\n\
+ FORMAT1<newline>FORMAT2, FORMAT1 applies to\n\
+ non-recent files and FORMAT2 to recent files;\n\
+ if STYLE is prefixed with `posix-', STYLE\n\
+ takes effect only outside the POSIX locale\n\
-t sort by modification time\n\
-T, --tabsize=COLS assume tab stops at each COLS instead of 8\n\
"), stdout);
fputs (_("\
-u with -lt: sort by, and show, access time\n\
- with -l: show access time and sort by name\n\
- otherwise: sort by access time\n\
+ with -l: show access time and sort by name\n\
+ otherwise: sort by access time\n\
-U do not sort; list entries in directory order\n\
-v sort by version\n\
"), stdout);
Index: src/mv.c
===================================================================
RCS file: /cvsroot/coreutils/coreutils/src/mv.c,v
retrieving revision 1.171
diff -u -p -r1.171 mv.c
--- src/mv.c 2 Nov 2005 21:52:33 -0000 1.171
+++ src/mv.c 23 Nov 2005 18:43:51 -0000
@@ -154,7 +154,7 @@ cp_option_init (struct cp_options *x)
static bool
target_directory_operand (char const *file)
{
- char const *b = base_name (file);
+ char const *b = last_component (file);
size_t blen = strlen (b);
bool looks_like_a_dir = (blen == 0 || ISSLASH (b[blen - 1]));
struct stat st;
@@ -272,7 +272,7 @@ movefile (char *source, char *dest, bool
if (dest_is_dir)
{
/* Treat DEST as a directory; build the full filename. */
- char const *src_basename = base_name (source);
+ char const *src_basename = last_component (source);
char *new_dest = file_name_concat (dest, src_basename, NULL);
strip_trailing_slashes (new_dest);
ok = do_move (source, new_dest, x);
@@ -315,15 +315,15 @@ Mandatory arguments to long options are
"), stdout);
fputs (_("\
--strip-trailing-slashes remove any trailing slashes from each SOURCE\n\
- argument\n\
+ argument\n\
-S, --suffix=SUFFIX override the usual backup suffix\n\
"), stdout);
fputs (_("\
-t, --target-directory=DIRECTORY move all SOURCE arguments into DIRECTORY\n\
-T, --no-target-directory treat DEST as a normal file\n\
-u, --update move only when the SOURCE file is newer\n\
- than the destination file or when the\n\
- destination file is missing\n\
+ than the destination file or when the\n\
+ destination file is missing\n\
-v, --verbose explain what is being done\n\
"), stdout);
fputs (HELP_OPTION_DESCRIPTION, stdout);
Index: src/remove.c
===================================================================
RCS file: /cvsroot/coreutils/coreutils/src/remove.c,v
retrieving revision 1.139
diff -u -p -r1.139 remove.c
--- src/remove.c 23 Nov 2005 04:52:48 -0000 1.139
+++ src/remove.c 23 Nov 2005 18:43:51 -0000
@@ -276,7 +276,7 @@ full_filename_ (Dirstack_state const *ds
if (n_allocated < n_bytes_needed)
{
/* This code requires that realloc accept NULL as the first arg.
- This function must not use xrealloc. Otherwise, an out-of-memory
+ This function must not use xrealloc. Otherwise, an out-of-memory
error involving a file name to be expanded here wouldn't ever
be issued. Use realloc and fall back on using a static buffer
if memory allocation fails. */
@@ -1322,7 +1322,7 @@ static enum RM_status
rm_1 (Dirstack_state *ds, char const *filename,
struct rm_options const *x, bool *cwd_restore_failed)
{
- char const *base = base_name (filename);
+ char const *base = last_component (filename);
if (DOT_OR_DOTDOT (base))
{
error (0, 0, _("cannot remove `.' or `..'"));
Index: src/rm.c
===================================================================
RCS file: /cvsroot/coreutils/coreutils/src/rm.c,v
retrieving revision 1.136
diff -u -p -r1.136 rm.c
--- src/rm.c 2 Nov 2005 21:53:20 -0000 1.136
+++ src/rm.c 23 Nov 2005 18:43:51 -0000
@@ -169,6 +169,7 @@ the contents of that file. If you want
truly unrecoverable, consider using shred.\n\
"), stdout);
printf (_("\nReport bugs to <%s>.\n"), PACKAGE_BUGREPORT);
+ free (base);
}
exit (status);
}
Index: src/shred.c
===================================================================
RCS file: /cvsroot/coreutils/coreutils/src/shred.c,v
retrieving revision 1.117
diff -u -p -r1.117 shred.c
--- src/shred.c 24 Sep 2005 13:40:37 -0000 1.117
+++ src/shred.c 23 Nov 2005 18:43:51 -0000
@@ -170,7 +170,7 @@ Mandatory arguments to long options are
-u, --remove truncate and remove file after overwriting\n\
-v, --verbose show progress\n\
-x, --exact do not round file sizes up to the next full block;\n\
- this is the default for non-regular files\n\
+ this is the default for non-regular files\n\
-z, --zero add a final overwrite with zeros to hide shredding\n\
"), stdout);
fputs (HELP_OPTION_DESCRIPTION, stdout);
@@ -258,7 +258,7 @@ struct isaac_state
/* This index operation is more efficient on many processors */
#define ind(mm, x) \
(* (uint32_t *) ((char *) (mm) \
- + ((x) & (ISAAC_WORDS - 1) * sizeof (uint32_t))))
+ + ((x) & (ISAAC_WORDS - 1) * sizeof (uint32_t))))
/*
* The central step. This uses two temporaries, x and y. mm is the
@@ -1344,7 +1344,7 @@ static bool
wipename (char *oldname, char const *qoldname, struct Options const *flags)
{
char *newname = xstrdup (oldname);
- char *base = base_name (newname);
+ char *base = last_component (newname);
size_t len = base_len (base);
char *dir = dir_name (newname);
char *qdir = xstrdup (quotearg_colon (dir));
Index: src/split.c
===================================================================
RCS file: /cvsroot/coreutils/coreutils/src/split.c,v
retrieving revision 1.112
diff -u -p -r1.112 split.c
--- src/split.c 11 Jul 2005 18:24:42 -0000 1.112
+++ src/split.c 23 Nov 2005 18:43:51 -0000
@@ -126,7 +126,7 @@ Mandatory arguments to long options are
"), DEFAULT_SUFFIX_LENGTH);
fputs (_("\
--verbose print a diagnostic to standard error just\n\
- before each output file is opened\n\
+ before each output file is opened\n\
"), stdout);
fputs (HELP_OPTION_DESCRIPTION, stdout);
fputs (VERSION_OPTION_DESCRIPTION, stdout);
@@ -171,7 +171,7 @@ next_file_name (void)
{
char *dir = dir_name (outfile);
long name_max = pathconf (dir, _PC_NAME_MAX);
- if (0 <= name_max && name_max < base_len (base_name (outfile)))
+ if (0 <= name_max && name_max < base_len (last_component (outfile)))
error (EXIT_FAILURE, ENAMETOOLONG, "%s", outfile);
free (dir);
}
@@ -237,7 +237,7 @@ bytes_split (uintmax_t n_bytes, char *bu
{
n_read = full_read (STDIN_FILENO, buf, bufsize);
if (n_read == SAFE_READ_ERROR)
- error (EXIT_FAILURE, errno, "%s", infile);
+ error (EXIT_FAILURE, errno, "%s", infile);
bp_out = buf;
to_read = n_read;
for (;;)
Index: src/su.c
===================================================================
RCS file: /cvsroot/coreutils/coreutils/src/su.c,v
retrieving revision 1.89
diff -u -p -r1.89 su.c
--- src/su.c 23 Aug 2005 15:09:13 -0000 1.89
+++ src/su.c 23 Nov 2005 18:43:51 -0000
@@ -219,7 +219,7 @@ log_su (struct passwd const *pw, bool su
if (!tty)
tty = "none";
/* 4.2BSD openlog doesn't have the third parameter. */
- openlog (base_name (program_name), 0
+ openlog (last_component (program_name), 0
# ifdef LOG_AUTH
, LOG_AUTH
# endif
@@ -282,7 +282,7 @@ modify_environment (const struct passwd
if (simulate_login)
{
/* Leave TERM unchanged. Set HOME, SHELL, USER, LOGNAME, PATH.
- Unset all other environment variables. */
+ Unset all other environment variables. */
char const *term = getenv ("TERM");
if (term)
term = xstrdup (term);
@@ -350,14 +350,14 @@ run_shell (char const *shell, char const
char *arg0;
char *shell_basename;
- shell_basename = base_name (shell);
+ shell_basename = last_component (shell);
arg0 = xmalloc (strlen (shell_basename) + 2);
arg0[0] = '-';
strcpy (arg0 + 1, shell_basename);
args[0] = arg0;
}
else
- args[0] = base_name (shell);
+ args[0] = last_component (shell);
if (fast_startup)
args[argno++] = "-f";
if (command)
Index: tests/Makefile.am
===================================================================
RCS file: /cvsroot/coreutils/coreutils/tests/Makefile.am,v
retrieving revision 1.24
diff -u -p -r1.24 Makefile.am
--- tests/Makefile.am 4 Nov 2005 09:51:42 -0000 1.24
+++ tests/Makefile.am 23 Nov 2005 18:43:51 -0000
@@ -19,7 +19,7 @@ EXTRA_DIST = \
rwx-to-mode sample-test setgid-check umask-check very-expensive
SUBDIRS = \
- basename chgrp chmod chown cp cut dd dircolors du expr factor \
+ basename chgrp chmod chown cp cut dd dircolors dirname du expr factor \
fmt head install join ln ls ls-2 md5sum misc mkdir mv od pr readlink \
rm rmdir seq sha1sum shred sort stty sum tac tail tail-2 tee test \
touch tr tsort unexpand uniq wc
Index: tests/basename/basic
===================================================================
RCS file: /cvsroot/coreutils/coreutils/tests/basename/basic,v
retrieving revision 1.6
diff -u -p -r1.6 basic
--- tests/basename/basic 20 Apr 2005 07:54:54 -0000 1.6
+++ tests/basename/basic 23 Nov 2005 18:43:52 -0000
@@ -14,12 +14,18 @@ d=$srcdir/..
exec $PERL -w -I$d -MCoreutils -- - << \EOF
require 5.003;
use strict;
+use File::stat;
(my $program_name = $0) =~ s|.*/||;
# Turn off localisation of executable's ouput.
@ENV{qw(LANGUAGE LANG LC_ALL)} = ('C') x 3;
+my $stat_single = stat('/');
+my $stat_double = stat('//');
+my $double_slash = ($stat_single->dev == $stat_double->dev
+ && $stat_single->ino == $stat_double->ino) ? '/' : '//';
+
my $prog = $ENV{PROG} || die "$0: \$PROG not specified in environment\n";
my @Tests =
@@ -35,15 +41,21 @@ my @Tests =
['d', qw(d/f//), {OUT => 'f'}],
['e', qw(f), {OUT => 'f'}],
['f', qw(/), {OUT => '/'}],
- ['g', qw(//), {OUT => '/'}],
+ ['g', qw(//), {OUT => "$double_slash"}],
['h', qw(///), {OUT => '/'}],
['i', qw(///a///), {OUT => 'a'}],
+ ['j', qw(''), {OUT => ''}],
['1', qw(f.s .s), {OUT => 'f'}],
['2', qw(fs s), {OUT => 'f'}],
['3', qw(fs fs), {OUT => 'fs'}],
- ['4', qw(fs fs), {OUT => 'fs'}],
+ ['4', qw(fs/ s), {OUT => 'f'}],
['5', qw(dir/file.suf .suf), {OUT => 'file'}],
- );
+ ['6', qw(// /), {OUT => "$double_slash"}],
+ ['7', qw(// //), {OUT => "$double_slash"}],
+ ['8', qw(fs x), {OUT => 'fs'}],
+ ['9', qw(fs ''), {OUT => 'fs'}],
+ ['10', qw(fs/ s/), {OUT => 'fs'}],
+ );
# Append a newline to end of each expected `OUT' string.
my $t;
Index: tests/dirname/Makefile.am
===================================================================
RCS file: tests/dirname/Makefile.am
diff -N tests/dirname/Makefile.am
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ tests/dirname/Makefile.am 23 Nov 2005 18:43:43 -0000
@@ -0,0 +1,11 @@
+## Process this file with automake to produce Makefile.in -*-Makefile-*-.
+AUTOMAKE_OPTIONS = 1.4 gnits
+
+TESTS = basic
+EXTRA_DIST = $(TESTS)
+TESTS_ENVIRONMENT = \
+ top_srcdir=$(top_srcdir) \
+ srcdir=$(srcdir) \
+ PERL="$(PERL)" \
+ PATH="`pwd`/../../src$(PATH_SEPARATOR)$$PATH" \
+ PROG=dirname
Index: tests/dirname/basic
===================================================================
RCS file: tests/dirname/basic
diff -N tests/dirname/basic
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ tests/dirname/basic 23 Nov 2005 18:43:43 -0000
@@ -0,0 +1,71 @@
+#!/bin/sh
+# -*-perl-*-
+
+: ${PERL=perl}
+: ${srcdir=.}
+
+$PERL -e 1 > /dev/null 2>&1 || {
+ echo 1>&2 "$0: configure didn't find a usable version of Perl," \
+ "so can't run this test"
+ exit 77
+}
+
+d=$srcdir/..
+exec $PERL -w -I$d -MCoreutils -- - << \EOF
+require 5.003;
+use strict;
+use File::stat;
+
+(my $program_name = $0) =~ s|.*/||;
+
+# Turn off localisation of executable's ouput.
address@hidden(LANGUAGE LANG LC_ALL)} = ('C') x 3;
+
+my $stat_single = stat('/');
+my $stat_double = stat('//');
+my $double_slash = ($stat_single->dev == $stat_double->dev
+ && $stat_single->ino == $stat_double->ino) ? '/' : '//';
+
+my $prog = $ENV{PROG} || die "$0: \$PROG not specified in environment\n";
+
+my @Tests =
+ (
+ ['fail-1', {ERR => "$prog: missing operand\n"
+ . "Try `$prog --help' for more information.\n"}, {EXIT => '1'}],
+ ['fail-2', qw(a b), {ERR => "$prog: extra operand `b'\n"
+ . "Try `$prog --help' for more information.\n"}, {EXIT => '1'}],
+
+ ['a', qw(d/f), {OUT => 'd'}],
+ ['b', qw(/d/f), {OUT => '/d'}],
+ ['c', qw(d/f/), {OUT => 'd'}],
+ ['d', qw(d/f//), {OUT => 'd'}],
+ ['e', qw(f), {OUT => '.'}],
+ ['f', qw(/), {OUT => '/'}],
+ ['g', qw(//), {OUT => "$double_slash"}],
+ ['h', qw(///), {OUT => '/'}],
+ ['i', qw(//a//), {OUT => "$double_slash"}],
+ ['j', qw(///a///), {OUT => '/'}],
+ ['k', qw(///a///b), {OUT => '///a'}],
+ ['l', qw(///a//b/), {OUT => '///a'}],
+ ['m', qw(''), {OUT => '.'}],
+ );
+
+# Append a newline to end of each expected `OUT' string.
+my $t;
+foreach $t (@Tests)
+ {
+ my $arg1 = $t->[1];
+ my $e;
+ foreach $e (@$t)
+ {
+ $e->{OUT} = "$e->{OUT}\n"
+ if ref $e eq 'HASH' and exists $e->{OUT};
+ }
+ }
+
+my $save_temps = $ENV{SAVE_TEMPS};
+my $verbose = $ENV{VERBOSE};
+
+my $fail = run_tests ($program_name, $prog, address@hidden, $save_temps,
$verbose);
+exit $fail;
+EOF
- Re: bugs in dirname module - coreutils portion,
Eric Blake <=