From 4b8000742fd12724cda7840b51daf9a6c821da95 Mon Sep 17 00:00:00 2001 From: Jim Meyering Date: Sat, 12 May 2001 14:23:49 +0000 Subject: [PATCH] (FILESYSTEM_PREFIX_LEN, PARAMS, ISSLASH): Remove; now in dirname.h. Do not include , ; no longer needed. Include , . (base_name): Allow file names ending in slashes, other than names that are all slashes. In this case, return the basename followed by the slashes. This is more general, and can be used in places where the original base_name purposely had an assertion failure. (base_len): New function. --- lib/basename.c | 74 ++++++++++++++++++++++++++++---------------------- 1 file changed, 41 insertions(+), 33 deletions(-) diff --git a/lib/basename.c b/lib/basename.c index 36e0f62b1..ff55b5800 100644 --- a/lib/basename.c +++ b/lib/basename.c @@ -19,53 +19,61 @@ # include #endif -#include -#include - -#ifndef FILESYSTEM_PREFIX_LEN -# define FILESYSTEM_PREFIX_LEN(Filename) 0 +#if STDC_HEADERS || HAVE_STRING_H +# include #endif - -#ifndef PARAMS -# if defined PROTOTYPES || (defined __STDC__ && __STDC__) -# define PARAMS(Args) Args -# else -# define PARAMS(Args) () -# endif -#endif - -#ifndef ISSLASH -# define ISSLASH(C) ((C) == '/') -#endif - -char *base_name PARAMS ((char const *name)); +#include /* In general, we can't use the builtin `basename' function if available, since it has different meanings in different environments. In some environments the builtin `basename' modifies its argument. - If NAME is all slashes, be sure to return `/'. */ + + Return the address of the last file name component of NAME. If + NAME has no file name components because it is all slashes, return + NAME if it is empty, the address of its last slash otherwise. */ char * base_name (char const *name) { - char const *base = name += FILESYSTEM_PREFIX_LEN (name); - int all_slashes = 1; + char const *base = name + FILESYSTEM_PREFIX_LEN (name); char const *p; - for (p = name; *p; p++) + for (p = base; *p; p++) { if (ISSLASH (*p)) - base = p + 1; - else - all_slashes = 0; + { + /* Treat multiple adjacent slashes like a single slash. */ + do p++; + while (ISSLASH (*p)); + + /* If the file name ends in slash, use the trailing slash as + the basename if no non-slashes have been found. */ + if (! *p) + { + if (ISSLASH (*base)) + base = p - 1; + break; + } + + /* *P is a non-slash preceded by a slash. */ + base = p; + } } - /* If NAME is all slashes, arrange to return `/'. */ - if (*base == '\0' && ISSLASH (*name) && all_slashes) - --base; - - /* Make sure the last byte is not a slash. */ - assert (all_slashes || !ISSLASH (*(p - 1))); - return (char *) base; } + +/* Return the length of of the basename NAME. Typically NAME is the + value returned by base_name. Act like strlen (NAME), except omit + redundant trailing slashes. */ + +size_t +base_len (char const *name) +{ + size_t len; + + for (len = strlen (name); 1 < len && ISSLASH (name[len - 1]); len--) + continue; + + return len; +}