-#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
-dir_name_r (char const *path, char const **result)
-{
- char const *slash;
- size_t length; /* Length of result, not including NUL. */
-
- slash = strrchr (path, '/');
- if (BACKSLASH_IS_PATH_SEPARATOR)
- {
- char const *b = strrchr (path, '\\');
- if (b && slash < b)
- slash = b;
- }
-
- /* If the last byte of PATH is a slash, decrement SLASH until it's
- pointing at the leftmost in a sequence of trailing slashes. */
- if (slash && slash[1] == 0)
- {
- while (path < slash && ISSLASH (slash[-1]))
- {
- --slash;
- }
-
- if (path < slash)
- {
- slash = memrchr (path, '/', slash - path);
- if (BACKSLASH_IS_PATH_SEPARATOR)
- {
- char const *b = memrchr (path, '\\', slash - path);
- if (b && slash < b)
- slash = b;
- }
- }
- }
-
- if (slash == 0)
- {
- /* File is in the current directory. */
- 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);
-
- /* If canonicalized "d:/path", leave alone the root case "d:/". */
- while (slash > lim && ISSLASH (*slash))
- --slash;
- }
- else
- {
- while (slash > path && ISSLASH (*slash))
- --slash;
- }
-
- length = slash - path + 1;
- }