summaryrefslogtreecommitdiffstats
path: root/gl/basename.c
diff options
context:
space:
mode:
Diffstat (limited to 'gl/basename.c')
-rw-r--r--gl/basename.c56
1 files changed, 31 insertions, 25 deletions
diff --git a/gl/basename.c b/gl/basename.c
index d73fd41..21fab1e 100644
--- a/gl/basename.c
+++ b/gl/basename.c
@@ -1,11 +1,11 @@
1/* basename.c -- return the last element in a file name 1/* basename.c -- return the last element in a file name
2 2
3 Copyright (C) 1990, 1998-2001, 2003-2006, 2009-2013 Free Software 3 Copyright (C) 1990, 1998-2001, 2003-2006, 2009-2023 Free Software
4 Foundation, Inc. 4 Foundation, Inc.
5 5
6 This program is free software: you can redistribute it and/or modify 6 This program is free software: you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by 7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3 of the License, or 8 the Free Software Foundation, either version 3 of the License, or
9 (at your option) any later version. 9 (at your option) any later version.
10 10
11 This program is distributed in the hope that it will be useful, 11 This program is distributed in the hope that it will be useful,
@@ -14,7 +14,7 @@
14 GNU General Public License for more details. 14 GNU General Public License for more details.
15 15
16 You should have received a copy of the GNU General Public License 16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>. */ 17 along with this program. If not, see <https://www.gnu.org/licenses/>. */
18 18
19#include <config.h> 19#include <config.h>
20 20
@@ -22,37 +22,43 @@
22 22
23#include <string.h> 23#include <string.h>
24#include "xalloc.h" 24#include "xalloc.h"
25#include "xstrndup.h"
26 25
27char * 26char *
28base_name (char const *name) 27base_name (char const *name)
29{ 28{
30 char const *base = last_component (name); 29 char const *base = last_component (name);
31 size_t length; 30 idx_t length;
32 31 int dotslash_len;
33 /* If there is no last component, then name is a file system root or the 32 if (*base)
34 empty string. */ 33 {
35 if (! *base) 34 length = base_len (base);
36 return xstrndup (name, base_len (name)); 35
37 36 /* Collapse a sequence of trailing slashes into one. */
38 /* Collapse a sequence of trailing slashes into one. */ 37 length += ISSLASH (base[length]);
39 length = base_len (base); 38
40 if (ISSLASH (base[length])) 39 /* On systems with drive letters, "a/b:c" must return "./b:c" rather
41 length++; 40 than "b:c" to avoid confusion with a drive letter. On systems
42 41 with pure POSIX semantics, this is not an issue. */
43 /* On systems with drive letters, "a/b:c" must return "./b:c" rather 42 dotslash_len = FILE_SYSTEM_PREFIX_LEN (base) != 0 ? 2 : 0;
44 than "b:c" to avoid confusion with a drive letter. On systems 43 }
45 with pure POSIX semantics, this is not an issue. */ 44 else
46 if (FILE_SYSTEM_PREFIX_LEN (base)) 45 {
46 /* There is no last component, so NAME is a file system root or
47 the empty string. */
48 base = name;
49 length = base_len (base);
50 dotslash_len = 0;
51 }
52
53 char *p = ximalloc (dotslash_len + length + 1);
54 if (dotslash_len)
47 { 55 {
48 char *p = xmalloc (length + 3);
49 p[0] = '.'; 56 p[0] = '.';
50 p[1] = '/'; 57 p[1] = '/';
51 memcpy (p + 2, base, length);
52 p[length + 2] = '\0';
53 return p;
54 } 58 }
55 59
56 /* Finally, copy the basename. */ 60 /* Finally, copy the basename. */
57 return xstrndup (base, length); 61 memcpy (p + dotslash_len, base, length);
62 p[dotslash_len + length] = '\0';
63 return p;
58} 64}