[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH 6/6] realpath: let --relative-base work even as child of --relati

From: Eric Blake
Subject: [PATCH 6/6] realpath: let --relative-base work even as child of --relative-to
Date: Wed, 14 Mar 2012 14:38:17 -0600

Consider: 'realpath --relative-base=$dir --relative-to=. $file'
It seems reasonable to get a relative name to $file if file is under
$dir, without regards to where '.' lives, but prior to this patch,
if '.' is a parent of $dir, the output was absolute.

* src/realpath.c (relpath): Relax filtering of base.
* doc/coreutils.texi (realpath invocation): Document this.
* tests/misc/realpath (out): Adjust test to match.
* NEWS: Document this.
 NEWS                |    4 +++-
 doc/coreutils.texi  |    6 +++---
 src/realpath.c      |    8 ++------
 tests/misc/realpath |    5 ++---
 4 files changed, 10 insertions(+), 13 deletions(-)

diff --git a/NEWS b/NEWS
index 5b53eb8..2740c24 100644
--- a/NEWS
+++ b/NEWS
@@ -69,7 +69,9 @@ GNU coreutils NEWS                                    -*- 
outline -*-
   fail with ENOTSUP or similar.

   'realpath --relative-base=dir' in isolation now implies '--relative-to=dir'
-  instead of causing a usage failure.
+  instead of causing a usage failure.  Additionally, the base
+  directory for deciding whether output will be relative can now be a
+  child of --relative-to directory.

   split now supports an unlimited number of split files as default behavior.

diff --git a/doc/coreutils.texi b/doc/coreutils.texi
index 10be715..1bd8a07 100644
--- a/doc/coreutils.texi
+++ b/doc/coreutils.texi
@@ -12905,9 +12905,9 @@ realpath invocation
 the output of @option{--relative-to} so that relative names are output,
 only when @var{file}s are descendants of @var{base}.  Otherwise output the
 absolute file name.  If @option{--relative-to} was not specified, then
-the descendants of @var{base} are printed relative to @var{base}.  If
-@option{--relative-to} is specified, then that directory must be a
-descendant of @var{base} for this option to have an effect.
+the descendants of @var{base} are printed relative to @var{base}.  The
+decision on whether to use relative output is independent from the
+directory that the output will be relative to.
 Note: this option honors the @option{-m} and @option{-e}
 options pertaining to file existence.  For example:

diff --git a/src/realpath.c b/src/realpath.c
index f5f212c..d7730da 100644
--- a/src/realpath.c
+++ b/src/realpath.c
@@ -180,12 +180,8 @@ relpath (const char *can_fname)
   if (can_relative_to)
       /* Enforce --relative-base.  */
-      if (can_relative_base)
-        {
-          if (!path_prefix (can_relative_base, can_fname)
-              || !path_prefix (can_relative_base, can_relative_to))
-            return false;
-        }
+      if (can_relative_base && !path_prefix (can_relative_base, can_fname))
+        return false;

       /* Skip the prefix common to --relative-to and path.  */
       int common_index = path_common_prefix (can_relative_to, can_fname);
diff --git a/tests/misc/realpath b/tests/misc/realpath
index 9484ac4..1635a1f 100755
--- a/tests/misc/realpath
+++ b/tests/misc/realpath
@@ -80,11 +80,10 @@ out=$(realpath -sm --relative-base=/usr /tmp /usr) || fail=1
 test "$out" = "/tmp$nl." || fail=1
 out=$(realpath -sm --relative-base=/ / /usr) || fail=1
 test "$out" = ".${nl}usr" || fail=1
-# For now, --relative-base must be a prefix of --relative-to, or all output
-# will be absolute (compare to MacOS 'relpath -d dir start end').
+# --relative-base can be a child of --relative-to
 out=$(realpath -sm --relative-base=/usr/local --relative-to=/usr \
     /usr /usr/local) || fail=1
-test "$out" = "/usr${nl}/usr/local" || fail=1
+test "$out" = "/usr${nl}local" || fail=1

 # Ensure // is handled correctly.
 test "$(realpath / // ///)" = "/$nl$double_slash$nl/" || fail=1

reply via email to

[Prev in Thread] Current Thread [Next in Thread]