1
1
/* basename -- strip directory and suffix from file names
2
Copyright (C) 1990-1997, 1999-2011 Free Software Foundation, Inc.
2
Copyright (C) 1990-2012 Free Software Foundation, Inc.
4
4
This program is free software: you can redistribute it and/or modify
5
5
it under the terms of the GNU General Public License as published by
14
14
You should have received a copy of the GNU General Public License
15
15
along with this program. If not, see <http://www.gnu.org/licenses/>. */
17
/* Usage: basename name [suffix]
18
NAME is a file name; SUFFIX is a suffix to strip from it.
20
basename /usr/foo/lossage/functions.l
22
basename /usr/foo/lossage/functions.l .l
24
basename functions.lisp p
27
17
#include <config.h>
28
18
#include <getopt.h>
30
20
#include <sys/types.h>
32
22
#include "system.h"
33
#include "long-options.h"
37
/* The official name of this program (e.g., no `g' prefix). */
26
/* The official name of this program (e.g., no 'g' prefix). */
38
27
#define PROGRAM_NAME "basename"
40
29
#define AUTHORS proper_name ("David MacKenzie")
31
static struct option const longopts[] =
33
{"multiple", no_argument, NULL, 'a'},
34
{"suffix", required_argument, NULL, 's'},
35
{"zero", no_argument, NULL, 'z'},
36
{GETOPT_HELP_OPTION_DECL},
37
{GETOPT_VERSION_OPTION_DECL},
45
44
if (status != EXIT_SUCCESS)
46
fprintf (stderr, _("Try `%s --help' for more information.\n"),
51
49
Usage: %s NAME [SUFFIX]\n\
50
or: %s OPTION... NAME...\n\
54
52
program_name, program_name);
57
55
If specified, also remove a trailing SUFFIX.\n\
60
-a, --multiple support multiple arguments and treat each as a NAME\n\
61
-s, --suffix=SUFFIX remove a trailing SUFFIX\n\
62
-z, --zero separate output with NUL rather than newline\n\
60
64
fputs (HELP_OPTION_DESCRIPTION, stdout);
61
65
fputs (VERSION_OPTION_DESCRIPTION, stdout);
65
%s /usr/bin/sort Output \"sort\".\n\
66
%s include/stdio.h .h Output \"stdio\".\n\
69
%s /usr/bin/sort -> \"sort\"\n\
70
%s include/stdio.h .h -> \"stdio\"\n\
71
%s -s .h include/stdio.h -> \"stdio\"\n\
72
%s -a any/str1 any/str2 -> \"str1\" followed by \"str2\"\n\
68
program_name, program_name);
74
program_name, program_name, program_name, program_name);
69
75
emit_ancillary_info ();
74
80
/* Remove SUFFIX from the end of NAME if it is there, unless NAME
75
consists entirely of SUFFIX. */
81
consists entirely of SUFFIX. */
78
84
remove_suffix (char *name, const char *suffix)
99
/* Perform the basename operation on STRING. If SUFFIX is non-NULL, remove
100
the trailing SUFFIX. Finally, output the result string. */
103
perform_basename (const char *string, const char *suffix, bool use_nuls)
105
char *name = base_name (string);
106
strip_trailing_slashes (name);
108
/* Per POSIX, 'basename // /' must return '//' on platforms with
109
distinct //. On platforms with drive letters, this generalizes
110
to making 'basename c: :' return 'c:'. This rule is captured by
111
skipping suffix stripping if base_name returned an absolute path
112
or a drive letter (only possible if name is a file-system
114
if (suffix && IS_RELATIVE_FILE_NAME (name) && ! FILE_SYSTEM_PREFIX_LEN (name))
115
remove_suffix (name, suffix);
117
fputs (name, stdout);
118
putchar (use_nuls ? '\0' : '\n');
94
123
main (int argc, char **argv)
125
bool multiple_names = false;
126
bool use_nuls = false;
127
const char *suffix = NULL;
98
129
initialize_main (&argc, &argv);
99
130
set_program_name (argv[0]);
104
135
atexit (close_stdout);
106
parse_long_options (argc, argv, PROGRAM_NAME, PACKAGE_NAME, Version,
107
usage, AUTHORS, (char const *) NULL);
108
if (getopt_long (argc, argv, "+", NULL, NULL) != -1)
109
usage (EXIT_FAILURE);
139
int c = getopt_long (argc, argv, "+as:z", longopts, NULL);
150
multiple_names = true;
157
case_GETOPT_HELP_CHAR;
158
case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
161
usage (EXIT_FAILURE);
111
165
if (argc < optind + 1)
114
168
usage (EXIT_FAILURE);
117
if (optind + 2 < argc)
171
if (!multiple_names && optind + 2 < argc)
119
173
error (0, 0, _("extra operand %s"), quote (argv[optind + 2]));
120
174
usage (EXIT_FAILURE);
123
name = base_name (argv[optind]);
124
strip_trailing_slashes (name);
126
/* Per POSIX, `basename // /' must return `//' on platforms with
127
distinct //. On platforms with drive letters, this generalizes
128
to making `basename c: :' return `c:'. This rule is captured by
129
skipping suffix stripping if base_name returned an absolute path
130
or a drive letter (only possible if name is a file-system
132
if (argc == optind + 2 && IS_RELATIVE_FILE_NAME (name)
133
&& ! FILE_SYSTEM_PREFIX_LEN (name))
134
remove_suffix (name, argv[optind + 1]);
179
for (; optind < argc; optind++)
180
perform_basename (argv[optind], suffix, use_nuls);
183
perform_basename (argv[optind],
184
optind + 2 == argc ? argv[optind + 1] : NULL, use_nuls);
139
186
exit (EXIT_SUCCESS);