I've noticed some behavior with make_relative_prefix that surprised
me. In particular, consider this program:
#include <stdio.h>
extern char * make_relative_prefix (const char *progname,
const char *bin_prefix,
const char *prefix);
int main () {
char *reloc;
reloc = make_relative_prefix ("/some/where/include/c++/4.2",
"/opt/foo/include/c++/4.2",
"/opt/foo");
printf ("%s\n", reloc);
}
I expected it to print:
/some/where/../../..
but, instead, it prints:
/some/where/include/c++/../../../../foo
It treats only "/opt" as a common component of the two paths, rathe
than "/opt/foo". If you use "/opt/foo/" (instead of "/opt/foo") for
the last argument, the answer is as I expected. This seems odd to me;
is it the intended behavior?
The patch below (which is against an older version of libiberty, and
might need updating) fixes it. Assuming you agree that this is a bug,
would this patch (with updating and testing) be OK?
Thanks,
--
Mark Mitchell
CodeSourcery
[EMAIL PROTECTED]
(650) 331-3385 x713
Index: libiberty/make-relative-prefix.c
===================================================================
--- libiberty/make-relative-prefix.c (revision 165621)
+++ libiberty/make-relative-prefix.c (working copy)
@@ -340,7 +340,23 @@ make_relative_prefix (const char *progna
n = (prefix_num < bin_num) ? prefix_num : bin_num;
for (common = 0; common < n; common++)
{
- if (strcmp (bin_dirs[common], prefix_dirs[common]) != 0)
+ const char *bin_dir;
+ const char *prefix_dir;
+ size_t bin_len;
+ size_t prefix_len;
+
+ /* Strip any trailing directory separators from the directories
+ before comparing them. */
+ bin_dir = bin_dirs[common];
+ bin_len = strlen (bin_dir);
+ if (IS_DIR_SEPARATOR (bin_dir[bin_len - 1]))
+ --bin_len;
+ prefix_dir = prefix_dirs[common];
+ prefix_len = strlen (prefix_dir);
+ if (IS_DIR_SEPARATOR (prefix_dir[prefix_len - 1]))
+ --prefix_len;
+ if (strncmp (bin_dir, prefix_dir,
+ (bin_len > prefix_len) ? bin_len : prefix_len) != 0)
break;
}