Skip to content

Commit 560b194

Browse files
committed
Refactor skipping DOS drive prefixes
Junio Hamano pointed out that there is an implicit assumption in pretty much all the code calling has_dos_drive_prefix(): it assumes that the DOS drive prefix is always two bytes long. While this assumption is pretty safe, we can still make the code more readable and less error-prone by introducing a function that skips the DOS drive prefix safely. Signed-off-by: Johannes Schindelin <[email protected]>
1 parent 5c01635 commit 560b194

File tree

5 files changed

+28
-22
lines changed

5 files changed

+28
-22
lines changed

compat/basename.c

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,7 @@
44
char *gitbasename (char *path)
55
{
66
const char *base;
7-
/* Skip over the disk name in MSDOS pathnames. */
8-
if (has_dos_drive_prefix(path))
9-
path += 2;
7+
skip_dos_drive_prefix(&path);
108
for (base = path; *path; path++) {
119
if (is_dir_sep(*path))
1210
base = path + 1;

compat/mingw.c

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1981,26 +1981,22 @@ pid_t waitpid(pid_t pid, int *status, int options)
19811981

19821982
int mingw_offset_1st_component(const char *path)
19831983
{
1984-
int offset = 0;
1985-
if (has_dos_drive_prefix(path))
1986-
offset = 2;
1984+
char *pos = (char *)path;
19871985

19881986
/* unc paths */
1989-
else if (is_dir_sep(path[0]) && is_dir_sep(path[1])) {
1990-
1987+
if (!skip_dos_drive_prefix(&pos) &&
1988+
is_dir_sep(pos[0]) && is_dir_sep(pos[1])) {
19911989
/* skip server name */
1992-
char *pos = strpbrk(path + 2, "\\/");
1990+
pos = strpbrk(pos + 2, "\\/");
19931991
if (!pos)
19941992
return 0; /* Error: malformed unc path */
19951993

19961994
do {
19971995
pos++;
19981996
} while (*pos && !is_dir_sep(*pos));
1999-
2000-
offset = pos - path;
20011997
}
20021998

2003-
return offset + is_dir_sep(path[offset]);
1999+
return pos + is_dir_sep(*pos) - path;
20042000
}
20052001

20062002
int xutftowcsn(wchar_t *wcs, const char *utfs, size_t wcslen, int utflen)

compat/mingw.h

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -383,7 +383,15 @@ HANDLE winansi_get_osfhandle(int fd);
383383
* git specific compatibility
384384
*/
385385

386-
#define has_dos_drive_prefix(path) (isalpha(*(path)) && (path)[1] == ':')
386+
#define has_dos_drive_prefix(path) \
387+
(isalpha(*(path)) && (path)[1] == ':' ? 2 : 0)
388+
static inline int mingw_skip_dos_drive_prefix(char **path)
389+
{
390+
int ret = has_dos_drive_prefix(*path);
391+
*path += ret;
392+
return ret;
393+
}
394+
#define skip_dos_drive_prefix mingw_skip_dos_drive_prefix
387395
#define is_dir_sep(c) ((c) == '/' || (c) == '\\')
388396
static inline char *mingw_find_last_dir_sep(const char *path)
389397
{

git-compat-util.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -335,6 +335,14 @@ static inline int git_has_dos_drive_prefix(const char *path)
335335
#define has_dos_drive_prefix git_has_dos_drive_prefix
336336
#endif
337337

338+
#ifndef skip_dos_drive_prefix
339+
static inline int git_skip_dos_drive_prefix(const char **path)
340+
{
341+
return 0;
342+
}
343+
#define skip_dos_drive_prefix git_skip_dos_drive_prefix
344+
#endif
345+
338346
#ifndef is_dir_sep
339347
static inline int git_is_dir_sep(int c)
340348
{

path.c

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -782,13 +782,10 @@ const char *relative_path(const char *in, const char *prefix,
782782
else if (!prefix_len)
783783
return in;
784784

785-
if (have_same_root(in, prefix)) {
785+
if (have_same_root(in, prefix))
786786
/* bypass dos_drive, for "c:" is identical to "C:" */
787-
if (has_dos_drive_prefix(in)) {
788-
i = 2;
789-
j = 2;
790-
}
791-
} else {
787+
i = j = has_dos_drive_prefix(in);
788+
else {
792789
return in;
793790
}
794791

@@ -943,11 +940,10 @@ const char *remove_leading_path(const char *in, const char *prefix)
943940
int normalize_path_copy_len(char *dst, const char *src, int *prefix_len)
944941
{
945942
char *dst0;
943+
int i;
946944

947-
if (has_dos_drive_prefix(src)) {
945+
for (i = has_dos_drive_prefix(src); i > 0; i--)
948946
*dst++ = *src++;
949-
*dst++ = *src++;
950-
}
951947
dst0 = dst;
952948

953949
if (is_dir_sep(*src)) {

0 commit comments

Comments
 (0)