From be17e3b98a178ea6e2c973bf49282f11f7060353 Mon Sep 17 00:00:00 2001 From: Eric Blake Date: Wed, 14 Mar 2012 13:42:59 -0600 Subject: realpath: optimize --relative-base usage MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There is no need to recompute for every path being visited whether the base is a prefix of the relative location. * src/realpath.c (relpath): Hoist base check... (main): ...here. Based on a suggestion by Pádraig Brady. --- src/realpath.c | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/src/realpath.c b/src/realpath.c index f95535b12..206f8006d 100644 --- a/src/realpath.c +++ b/src/realpath.c @@ -179,12 +179,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); @@ -341,13 +337,25 @@ main (int argc, char **argv) if (need_dir && !isdir (can_relative_to)) error (EXIT_FAILURE, ENOTDIR, "%s", quote (relative_to)); } - if (relative_base) + if (relative_base == relative_to) + can_relative_base = can_relative_to; + else if (relative_base) { - can_relative_base = realpath_canon (relative_base, can_mode); - if (!can_relative_base) + char *base = realpath_canon (relative_base, can_mode); + if (!base) error (EXIT_FAILURE, errno, "%s", quote (relative_base)); - if (need_dir && !isdir (can_relative_base)) + if (need_dir && !isdir (base)) error (EXIT_FAILURE, ENOTDIR, "%s", quote (relative_base)); + /* --relative-to is a no-op if it does not have --relative-base + as a prefix */ + if (path_prefix (base, can_relative_to)) + can_relative_base = base; + else + { + free (base); + can_relative_base = can_relative_to; + can_relative_to = NULL; + } } for (; optind < argc; ++optind) -- cgit v1.2.3-54-g00ecf