diff options
| author | Denys Vlasenko <vda.linux@googlemail.com> | 2021-09-09 23:45:13 +0200 |
|---|---|---|
| committer | Denys Vlasenko <vda.linux@googlemail.com> | 2021-09-09 23:45:13 +0200 |
| commit | 0599e0f87bcaa4b9f91652fa53bc29a3bdacfa13 (patch) | |
| tree | d27c9b54ba863b5ae0b669b0a864b301e30c9abb /coreutils | |
| parent | 7ab9cd23988b48956fcfe171d5828d61285baf40 (diff) | |
| download | busybox-w32-0599e0f87bcaa4b9f91652fa53bc29a3bdacfa13.tar.gz busybox-w32-0599e0f87bcaa4b9f91652fa53bc29a3bdacfa13.tar.bz2 busybox-w32-0599e0f87bcaa4b9f91652fa53bc29a3bdacfa13.zip | |
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>
Diffstat (limited to 'coreutils')
| -rw-r--r-- | coreutils/basename.c | 62 |
1 files changed, 38 insertions, 24 deletions
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 @@ | |||
| 29 | /* http://www.opengroup.org/onlinepubs/007904975/utilities/basename.html */ | 29 | /* http://www.opengroup.org/onlinepubs/007904975/utilities/basename.html */ |
| 30 | 30 | ||
| 31 | //usage:#define basename_trivial_usage | 31 | //usage:#define basename_trivial_usage |
| 32 | //usage: "FILE [SUFFIX]" | 32 | //usage: "FILE [SUFFIX] | -a FILE... | -s SUFFIX FILE..." |
| 33 | //usage:#define basename_full_usage "\n\n" | 33 | //usage:#define basename_full_usage "\n\n" |
| 34 | //usage: "Strip directory path and .SUFFIX from FILE" | 34 | //usage: "Strip directory path and SUFFIX from FILE\n" |
| 35 | //usage: "\n -a All arguments are FILEs" | ||
| 36 | //usage: "\n -s SUFFIX Remove SUFFIX (implies -a)" | ||
| 35 | //usage: | 37 | //usage: |
| 36 | //usage:#define basename_example_usage | 38 | //usage:#define basename_example_usage |
| 37 | //usage: "$ basename /usr/local/bin/foo\n" | 39 | //usage: "$ basename /usr/local/bin/foo\n" |
| @@ -48,31 +50,43 @@ | |||
| 48 | int basename_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 50 | int basename_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
| 49 | int basename_main(int argc UNUSED_PARAM, char **argv) | 51 | int basename_main(int argc UNUSED_PARAM, char **argv) |
| 50 | { | 52 | { |
| 51 | size_t m, n; | 53 | unsigned opts; |
| 52 | char *s; | 54 | const char *suffix = NULL; |
| 53 | 55 | ||
| 54 | if (argv[1] && strcmp(argv[1], "--") == 0) { | 56 | /* '+': stop at first non-option */ |
| 55 | argv++; | 57 | opts = getopt32(argv, "^+" "as:" |
| 56 | } | 58 | "\0" "-1" /* At least one argument */ |
| 57 | if (!argv[1]) | 59 | , &suffix |
| 58 | bb_show_usage(); | 60 | ); |
| 61 | argv += optind; | ||
| 59 | 62 | ||
| 60 | /* It should strip slash: /abc/def/ -> def */ | 63 | do { |
| 61 | s = bb_get_last_path_component_strip(*++argv); | 64 | char *s; |
| 65 | size_t m; | ||
| 62 | 66 | ||
| 63 | m = strlen(s); | 67 | /* It should strip slash: /abc/def/ -> def */ |
| 64 | if (*++argv) { | 68 | s = bb_get_last_path_component_strip(*argv++); |
| 65 | if (argv[1]) | 69 | m = strlen(s); |
| 66 | bb_show_usage(); | 70 | if (!opts) { |
| 67 | n = strlen(*argv); | 71 | if (*argv) { |
| 68 | if ((m > n) && (strcmp(s+m-n, *argv) == 0)) { | 72 | suffix = *argv; |
| 69 | m -= n; | 73 | if (argv[1]) |
| 70 | /*s[m] = '\0'; - redundant */ | 74 | bb_show_usage(); |
| 75 | } | ||
| 71 | } | 76 | } |
| 72 | } | 77 | if (suffix) { |
| 78 | size_t n = strlen(suffix); | ||
| 79 | if ((m > n) && (strcmp(s + m - n, suffix) == 0)) { | ||
| 80 | m -= n; | ||
| 81 | /*s[m] = '\0'; - redundant */ | ||
| 82 | } | ||
| 83 | } | ||
| 84 | /* puts(s) will do, but we can do without stdio this way: */ | ||
| 85 | s[m++] = '\n'; | ||
| 86 | /* NB: != is correct here: */ | ||
| 87 | if (full_write(STDOUT_FILENO, s, m) != (ssize_t)m) | ||
| 88 | return EXIT_FAILURE; | ||
| 89 | } while (opts && *argv); | ||
| 73 | 90 | ||
| 74 | /* puts(s) will do, but we can do without stdio this way: */ | 91 | return EXIT_SUCCESS; |
| 75 | s[m++] = '\n'; | ||
| 76 | /* NB: != is correct here: */ | ||
| 77 | return full_write(STDOUT_FILENO, s, m) != (ssize_t)m; | ||
| 78 | } | 92 | } |
