Mercurial > hg > octave-lojdl > gnulib-hg
changeset 3038:e42896c5352d
(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.
author | Jim Meyering <jim@meyering.net> |
---|---|
date | Thu, 07 Dec 2000 14:10:21 +0000 |
parents | e6757ccfb526 |
children | cd8da840fa9d |
files | lib/dirname.c |
diffstat | 1 files changed, 32 insertions(+), 25 deletions(-) [+] |
line wrap: on
line diff
--- a/lib/dirname.c +++ b/lib/dirname.c @@ -43,17 +43,23 @@ #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 @@ 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 @@ 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 @@ { 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; }