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; }