@@ -21,45 +21,78 @@ static struct {
21
21
.result = RESULT_NONE ,
22
22
};
23
23
24
- #ifndef _MSC_VER
25
- #define make_relative (location ) location
26
- #else
27
24
/*
28
25
* Visual C interpolates the absolute Windows path for `__FILE__`,
29
26
* 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.
30
29
*/
31
30
#include "dir.h"
32
31
33
32
static const char * make_relative (const char * location )
34
33
{
35
34
static char prefix [] = __FILE__ , buf [PATH_MAX ], * p ;
36
35
static size_t prefix_len ;
36
+ static int need_bs_to_fs = -1 ;
37
37
38
- if (!prefix_len ) {
38
+ /* one-time preparation */
39
+ if (need_bs_to_fs < 0 ) {
39
40
size_t len = strlen (prefix );
40
- const char * needle = "\\ t\\unit-tests\\test-lib.c" ;
41
+ char needle [] = "t\\unit-tests\\test-lib.c" ;
41
42
size_t needle_len = strlen (needle );
42
43
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
+ }
45
62
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 );
48
73
}
49
74
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 ))
52
80
return location ;
53
81
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
+
55
89
/* convert backslashes to forward slashes */
90
+ strlcpy (buf , location + prefix_len , sizeof (buf ));
56
91
for (p = buf ; * p ; p ++ )
57
92
if (* p == '\\' )
58
93
* p = '/' ;
59
-
60
94
return buf ;
61
95
}
62
- #endif
63
96
64
97
static void msg_with_prefix (const char * prefix , const char * format , va_list ap )
65
98
{
0 commit comments