diff --git a/coreutils/basename.c b/coreutils/basename.c index 0dd2c43c7..0b721c03c 100644 --- a/coreutils/basename.c +++ b/coreutils/basename.c @@ -29,9 +29,11 @@ /* http://www.opengroup.org/onlinepubs/007904975/utilities/basename.html */ //usage:#define basename_trivial_usage -//usage: "FILE [SUFFIX]" +//usage: "FILE [SUFFIX] | -a FILE... | -s SUFFIX FILE..." //usage:#define basename_full_usage "\n\n" -//usage: "Strip directory path and .SUFFIX from FILE" +//usage: "Strip directory path and SUFFIX from FILE\n" +//usage: "\n -a All arguments are FILEs" +//usage: "\n -s SUFFIX Remove SUFFIX (implies -a)" //usage: //usage:#define basename_example_usage //usage: "$ basename /usr/local/bin/foo\n" @@ -48,31 +50,43 @@ int basename_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; int basename_main(int argc UNUSED_PARAM, char **argv) { - size_t m, n; - char *s; + unsigned opts; + const char *suffix = NULL; - if (argv[1] && strcmp(argv[1], "--") == 0) { - argv++; - } - if (!argv[1]) - bb_show_usage(); + /* '+': stop at first non-option */ + opts = getopt32(argv, "^+" "as:" + "\0" "-1" /* At least one argument */ + , &suffix + ); + argv += optind; - /* It should strip slash: /abc/def/ -> def */ - s = bb_get_last_path_component_strip(*++argv); + do { + char *s; + size_t m; - m = strlen(s); - if (*++argv) { - if (argv[1]) - bb_show_usage(); - n = strlen(*argv); - if ((m > n) && (strcmp(s+m-n, *argv) == 0)) { - m -= n; - /*s[m] = '\0'; - redundant */ + /* It should strip slash: /abc/def/ -> def */ + s = bb_get_last_path_component_strip(*argv++); + m = strlen(s); + if (!opts) { + if (*argv) { + suffix = *argv; + if (argv[1]) + bb_show_usage(); + } } - } + if (suffix) { + size_t n = strlen(suffix); + if ((m > n) && (strcmp(s + m - n, suffix) == 0)) { + m -= n; + /*s[m] = '\0'; - redundant */ + } + } + /* puts(s) will do, but we can do without stdio this way: */ + s[m++] = '\n'; + /* NB: != is correct here: */ + if (full_write(STDOUT_FILENO, s, m) != (ssize_t)m) + return EXIT_FAILURE; + } while (opts && *argv); - /* puts(s) will do, but we can do without stdio this way: */ - s[m++] = '\n'; - /* NB: != is correct here: */ - return full_write(STDOUT_FILENO, s, m) != (ssize_t)m; + return EXIT_SUCCESS; }