basename: implement -a and -s SUFFIX

function                                             old     new   delta
basename_main                                        145     207     +62
packed_usage                                       33914   33950     +36
.rodata                                           104241  104250      +9
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 3/0 up/down: 107/0)             Total: 107 bytes

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
diff --git a/coreutils/basename.c b/coreutils/basename.c
index 0dd2c43..0b721c0 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;
 }