Line data Source code
1 : /* basename -- strip directory and suffix from file names
2 : Copyright (C) 1990-1997, 1999-2007 Free Software Foundation, Inc.
3 :
4 : This program is free software: you can redistribute it and/or modify
5 : it under the terms of the GNU General Public License as published by
6 : the Free Software Foundation, either version 3 of the License, or
7 : (at your option) any later version.
8 :
9 : This program is distributed in the hope that it will be useful,
10 : but WITHOUT ANY WARRANTY; without even the implied warranty of
11 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 : GNU General Public License for more details.
13 :
14 : You should have received a copy of the GNU General Public License
15 : along with this program. If not, see <http://www.gnu.org/licenses/>. */
16 :
17 : /* Usage: basename name [suffix]
18 : NAME is a file name; SUFFIX is a suffix to strip from it.
19 :
20 : basename /usr/foo/lossage/functions.l
21 : => functions.l
22 : basename /usr/foo/lossage/functions.l .l
23 : => functions
24 : basename functions.lisp p
25 : => functions.lis */
26 :
27 : #include <config.h>
28 : #include <getopt.h>
29 : #include <stdio.h>
30 : #include <sys/types.h>
31 :
32 : #include "system.h"
33 : #include "long-options.h"
34 : #include "error.h"
35 : #include "quote.h"
36 :
37 : /* The official name of this program (e.g., no `g' prefix). */
38 : #define PROGRAM_NAME "basename"
39 :
40 : #define AUTHORS "FIXME unknown"
41 :
42 : /* The name this program was run with. */
43 : char *program_name;
44 :
45 : void
46 24 : usage (int status)
47 : {
48 24 : if (status != EXIT_SUCCESS)
49 22 : fprintf (stderr, _("Try `%s --help' for more information.\n"),
50 : program_name);
51 : else
52 : {
53 2 : printf (_("\
54 : Usage: %s NAME [SUFFIX]\n\
55 : or: %s OPTION\n\
56 : "),
57 : program_name, program_name);
58 2 : fputs (_("\
59 : Print NAME with any leading directory components removed.\n\
60 : If specified, also remove a trailing SUFFIX.\n\
61 : \n\
62 : "), stdout);
63 2 : fputs (HELP_OPTION_DESCRIPTION, stdout);
64 2 : fputs (VERSION_OPTION_DESCRIPTION, stdout);
65 2 : printf (_("\
66 : \n\
67 : Examples:\n\
68 : %s /usr/bin/sort Output \"sort\".\n\
69 : %s include/stdio.h .h Output \"stdio\".\n\
70 : "),
71 : program_name, program_name);
72 2 : emit_bug_reporting_address ();
73 : }
74 24 : exit (status);
75 : }
76 :
77 : /* Remove SUFFIX from the end of NAME if it is there, unless NAME
78 : consists entirely of SUFFIX. */
79 :
80 : static void
81 6 : remove_suffix (char *name, const char *suffix)
82 : {
83 : char *np;
84 : const char *sp;
85 :
86 6 : np = name + strlen (name);
87 6 : sp = suffix + strlen (suffix);
88 :
89 13 : while (np > name && sp > suffix)
90 2 : if (*--np != *--sp)
91 1 : return;
92 5 : if (np > name)
93 3 : *np = '\0';
94 : }
95 :
96 : int
97 37 : main (int argc, char **argv)
98 : {
99 : char *name;
100 :
101 : initialize_main (&argc, &argv);
102 37 : program_name = argv[0];
103 37 : setlocale (LC_ALL, "");
104 : bindtextdomain (PACKAGE, LOCALEDIR);
105 : textdomain (PACKAGE);
106 :
107 37 : atexit (close_stdout);
108 :
109 37 : parse_long_options (argc, argv, PROGRAM_NAME, PACKAGE_NAME, VERSION,
110 : usage, AUTHORS, (char const *) NULL);
111 33 : if (getopt_long (argc, argv, "+", NULL, NULL) != -1)
112 5 : usage (EXIT_FAILURE);
113 :
114 28 : if (argc < optind + 1)
115 : {
116 2 : error (0, 0, _("missing operand"));
117 2 : usage (EXIT_FAILURE);
118 : }
119 :
120 26 : if (optind + 2 < argc)
121 : {
122 15 : error (0, 0, _("extra operand %s"), quote (argv[optind + 2]));
123 15 : usage (EXIT_FAILURE);
124 : }
125 :
126 11 : name = base_name (argv[optind]);
127 11 : strip_trailing_slashes (name);
128 :
129 : /* Per POSIX, `basename // /' must return `//' on platforms with
130 : distinct //. On platforms with drive letters, this generalizes
131 : to making `basename c: :' return `c:'. This rule is captured by
132 : skipping suffix stripping if base_name returned an absolute path
133 : or a drive letter (only possible if name is a file-system
134 : root). */
135 11 : if (argc == optind + 2 && IS_RELATIVE_FILE_NAME (name)
136 8 : && ! FILE_SYSTEM_PREFIX_LEN (name))
137 6 : remove_suffix (name, argv[optind + 1]);
138 :
139 11 : puts (name);
140 11 : free (name);
141 :
142 11 : exit (EXIT_SUCCESS);
143 : }
|