@@ -21,45 +21,78 @@ static struct {
2121 .result = RESULT_NONE ,
2222};
2323
24- #ifndef _MSC_VER
25- #define make_relative (location ) location
26- #else
2724/*
2825 * Visual C interpolates the absolute Windows path for `__FILE__`,
2926 * but we want to see relative paths, as verified by t0080.
27+ * There are other compilers that do the same, and are not for
28+ * Windows.
3029 */
3130#include "dir.h"
3231
3332static const char * make_relative (const char * location )
3433{
3534 static char prefix [] = __FILE__ , buf [PATH_MAX ], * p ;
3635 static size_t prefix_len ;
36+ static int need_bs_to_fs = -1 ;
3737
38- if (!prefix_len ) {
38+ /* one-time preparation */
39+ if (need_bs_to_fs < 0 ) {
3940 size_t len = strlen (prefix );
40- const char * needle = "\\ t\\unit-tests\\test-lib.c" ;
41+ char needle [] = "t\\unit-tests\\test-lib.c" ;
4142 size_t needle_len = strlen (needle );
4243
43- if (len < needle_len || strcmp (needle , prefix + len - needle_len ))
44- die ("unexpected suffix of '%s'" , prefix );
44+ if (len < needle_len )
45+ die ("unexpected prefix '%s'" , prefix );
46+
47+ /*
48+ * The path could be relative (t/unit-tests/test-lib.c)
49+ * or full (/home/user/git/t/unit-tests/test-lib.c).
50+ * Check the slash between "t" and "unit-tests".
51+ */
52+ prefix_len = len - needle_len ;
53+ if (prefix [prefix_len + 1 ] == '/' ) {
54+ /* Oh, we're not Windows */
55+ for (size_t i = 0 ; i < needle_len ; i ++ )
56+ if (needle [i ] == '\\' )
57+ needle [i ] = '/' ;
58+ need_bs_to_fs = 0 ;
59+ } else {
60+ need_bs_to_fs = 1 ;
61+ }
4562
46- /* let it end in a directory separator */
47- prefix_len = len - needle_len + 1 ;
63+ /*
64+ * prefix_len == 0 if the compiler gives paths relative
65+ * to the root of the working tree. Otherwise, we want
66+ * to see that we did find the needle[] at a directory
67+ * boundary. Again we rely on that needle[] begins with
68+ * "t" followed by the directory separator.
69+ */
70+ if (fspathcmp (needle , prefix + prefix_len ) ||
71+ (prefix_len && prefix [prefix_len - 1 ] != needle [1 ]))
72+ die ("unexpected suffix of '%s'" , prefix );
4873 }
4974
50- /* Does it not start with the expected prefix? */
51- if (fspathncmp (location , prefix , prefix_len ))
75+ /*
76+ * Does it not start with the expected prefix?
77+ * Return it as-is without making it worse.
78+ */
79+ if (prefix_len && fspathncmp (location , prefix , prefix_len ))
5280 return location ;
5381
54- strlcpy (buf , location + prefix_len , sizeof (buf ));
82+ /*
83+ * If we do not need to munge directory separator, we can return
84+ * the substring at the tail of the location.
85+ */
86+ if (!need_bs_to_fs )
87+ return location + prefix_len ;
88+
5589 /* convert backslashes to forward slashes */
90+ strlcpy (buf , location + prefix_len , sizeof (buf ));
5691 for (p = buf ; * p ; p ++ )
5792 if (* p == '\\' )
5893 * p = '/' ;
59-
6094 return buf ;
6195}
62- #endif
6396
6497static void msg_with_prefix (const char * prefix , const char * format , va_list ap )
6598{
0 commit comments