diff options
Diffstat (limited to 'contrib/bmake/dirname.c')
-rw-r--r-- | contrib/bmake/dirname.c | 89 |
1 files changed, 57 insertions, 32 deletions
diff --git a/contrib/bmake/dirname.c b/contrib/bmake/dirname.c index 8b6b6c3..154593b 100644 --- a/contrib/bmake/dirname.c +++ b/contrib/bmake/dirname.c @@ -1,4 +1,4 @@ -/* $NetBSD: dirname.c,v 1.11 2009/11/24 13:34:20 tnozaki Exp $ */ +/* $NetBSD: dirname.c,v 1.13 2014/07/16 10:52:26 christos Exp $ */ /*- * Copyright (c) 1997, 2002 The NetBSD Foundation, Inc. @@ -35,7 +35,10 @@ #ifndef HAVE_DIRNAME #include <sys/cdefs.h> - +#include <sys/param.h> +#ifdef HAVE_LIBGEN_H +#include <libgen.h> +#endif #ifdef HAVE_LIMITS_H #include <limits.h> #endif @@ -45,51 +48,73 @@ #ifndef PATH_MAX # define PATH_MAX 1024 #endif +#ifndef MIN +# define MIN(a, b) ((a < b) ? a : b) +#endif -char * -dirname(char *path) + +static size_t +xdirname_r(const char *path, char *buf, size_t buflen) { - static char result[PATH_MAX]; - const char *lastp; + const char *endp; size_t len; /* * If `path' is a null pointer or points to an empty string, * return a pointer to the string ".". */ - if ((path == NULL) || (*path == '\0')) - goto singledot; - + if (path == NULL || *path == '\0') { + path = "."; + len = 1; + goto out; + } /* Strip trailing slashes, if any. */ - lastp = path + strlen(path) - 1; - while (lastp != path && *lastp == '/') - lastp--; + endp = path + strlen(path) - 1; + while (endp != path && *endp == '/') + endp--; - /* Terminate path at the last occurence of '/'. */ - do { - if (*lastp == '/') { - /* Strip trailing slashes, if any. */ - while (lastp != path && *lastp == '/') - lastp--; + /* Find the start of the dir */ + while (endp > path && *endp != '/') + endp--; - /* ...and copy the result into the result buffer. */ - len = (lastp - path) + 1 /* last char */; - if (len > (PATH_MAX - 1)) - len = PATH_MAX - 1; + if (endp == path) { + path = *endp == '/' ? "/" : "."; + len = 1; + goto out; + } - memcpy(result, path, len); - result[len] = '\0'; + do + endp--; + while (endp > path && *endp == '/'); - return (result); - } - } while (--lastp >= path); + len = endp - path + 1; +out: + if (buf != NULL && buflen != 0) { + buflen = MIN(len, buflen - 1); + memcpy(buf, path, buflen); + buf[buflen] = '\0'; + } + return len; +} - /* No /'s found, return a pointer to the string ".". */ -singledot: - result[0] = '.'; - result[1] = '\0'; +char * +dirname(char *path) +{ + static char result[PATH_MAX]; + (void)xdirname_r(path, result, sizeof(result)); + return result; +} + +#ifdef MAIN +#include <stdlib.h> +#include <stdio.h> - return (result); +int +main(int argc, char *argv[]) +{ + printf("%s\n", dirname(argv[1])); + exit(0); } #endif +#endif |