diff options
author | Jim Meyering <jim@meyering.net> | 2000-12-07 14:10:21 +0000 |
---|---|---|
committer | Jim Meyering <jim@meyering.net> | 2000-12-07 14:10:21 +0000 |
commit | 4504b81f3b9a1071834012262bd4eac17f9290ff (patch) | |
tree | 5a0a24e2ec6dcc8d8db1e8b0650ff8414cfd8e2a /lib | |
parent | 222412dbf14be2eeeab5ab0139e3a7b11169942c (diff) | |
download | coreutils-4504b81f3b9a1071834012262bd4eac17f9290ff.tar.xz |
(FILESYSTEM_PREFIX_LEN): Define.
(dir_name_r): Declare this function as static.
[BACKSLASH_IS_PATH_SEPARATOR]: Fix a bug that'd
manifest itself on a name containing a mix of slashes and
backslashes.
Make this function work with names starting with a DOS-style
drive letter and colon prefix.
(dir_name): Append `.' if necessary.
Based mostly on patches from Prashant TR and Eli Zaretskii.
Diffstat (limited to 'lib')
-rw-r--r-- | lib/dirname.c | 57 |
1 files changed, 32 insertions, 25 deletions
diff --git a/lib/dirname.c b/lib/dirname.c index 2225800ab..7826d8edb 100644 --- a/lib/dirname.c +++ b/lib/dirname.c @@ -43,17 +43,23 @@ void *memrchr (); #include "dirname.h" +#ifndef FILESYSTEM_PREFIX_LEN +# define FILESYSTEM_PREFIX_LEN(Filename) 0 +#endif + #ifndef ISSLASH # define ISSLASH(C) ((C) == '/') #endif #define BACKSLASH_IS_PATH_SEPARATOR ISSLASH ('\\') -/* Return the length of `dirname (PATH)' and set *RESULT - to point to PATH or to `"."', as appropriate. - Works properly even if there are trailing slashes - (by effectively ignoring them). */ -size_t +/* Return the length of `dirname (PATH)' and set *RESULT to point + to PATH or to `"."', as appropriate. Works properly even if + there are trailing slashes (by effectively ignoring them). + WARNING: This function doesn't work for cwd-relative names like + `a:foo' that are specified with a drive-letter prefix. That case + is handled in the caller. */ +static size_t dir_name_r (char const *path, char const **result) { char const *slash; @@ -78,10 +84,11 @@ dir_name_r (char const *path, char const **result) if (path < slash) { - slash = memrchr (path, '/', slash - path); + size_t len = slash - path; + slash = memrchr (path, '/', len); if (BACKSLASH_IS_PATH_SEPARATOR) { - char const *b = memrchr (path, '\\', slash - path); + char const *b = memrchr (path, '\\', len); if (b && slash < b) slash = b; } @@ -91,27 +98,23 @@ dir_name_r (char const *path, char const **result) if (slash == 0) { /* File is in the current directory. */ - path = "."; - length = 1; + + length = FILESYSTEM_PREFIX_LEN (path); + + if (length == 0) + { + path = "."; + length = 1; + } } else { - /* Remove any trailing slashes from the result. */ - if (BACKSLASH_IS_PATH_SEPARATOR) - { - char const *lim = ((path[0] >= 'A' && path[0] <= 'z' - && path[1] == ':') - ? path + 2 : path); + /* Remove any trailing slashes from the result. If we have a + canonicalized "d:/path", leave alone the root case "d:/". */ + char const *lim = path + FILESYSTEM_PREFIX_LEN (path); - /* If canonicalized "d:/path", leave alone the root case "d:/". */ - while (slash > lim && ISSLASH (*slash)) - --slash; - } - else - { - while (slash > path && ISSLASH (*slash)) - --slash; - } + while (slash > lim && ISSLASH (*slash)) + --slash; length = slash - path + 1; } @@ -130,10 +133,14 @@ dir_name (char const *path) { char const *result; size_t length = dir_name_r (path, &result); - char *newpath = (char *) malloc (length + 1); + int append_dot = (length && length == FILESYSTEM_PREFIX_LEN (newpath)); + char *newpath = (char *) malloc (length + append_dot + 1); if (newpath == 0) return 0; strncpy (newpath, result, length); + /* If PATH is "d:foo", return "d:.", the CWD on drive d: */ + if (append_dot) + newpath[length++] = '.'; newpath[length] = 0; return newpath; } |