diff options
author | Johannes Schindelin <johannes.schindelin@gmx.de> | 2017-08-08 16:46:39 +0200 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2017-08-09 13:52:17 +0200 |
commit | 3bef5d89b0c667e9fb7d1d9b44ba9b30d4d084e4 (patch) | |
tree | 5f31bceb5e2b239d88f6465cc76f313a4d5ddc98 /shell | |
parent | 5856dc74be79fa288f481e1f19077518ae6d8303 (diff) |
ash: implement -d DELIM option for read
The POSIX standard only requires the read builtin to handle -r:
http://pubs.opengroup.org/onlinepubs/9699919799/utilities/read.html
However, Bash introduced the option -d <DELIM> to override IFS for
just one invocation, and it is quite useful.
It is also super easy to implement in BusyBox' ash, so let's do that.
The motivation: This option is used by Git's test suite.
function old new delta
.rodata 163505 163587 +82
shell_builtin_read 1244 1289 +45
readcmd 233 259 +26
builtin_read 258 263 +5
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 4/0 up/down: 158/0) Total: 158 bytes
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'shell')
-rw-r--r-- | shell/ash.c | 15 | ||||
-rw-r--r-- | shell/shell_common.c | 10 | ||||
-rw-r--r-- | shell/shell_common.h | 3 |
3 files changed, 21 insertions, 7 deletions
diff --git a/shell/ash.c b/shell/ash.c index 6dc1cfef7..fd1772351 100644 --- a/shell/ash.c +++ b/shell/ash.c @@ -189,6 +189,8 @@ #define BASH_HOSTNAME_VAR ENABLE_ASH_BASH_COMPAT #define BASH_SHLVL_VAR ENABLE_ASH_BASH_COMPAT #define BASH_XTRACEFD ENABLE_ASH_BASH_COMPAT +#define BASH_READ_D ENABLE_ASH_BASH_COMPAT +#define IF_BASH_READ_D IF_ASH_BASH_COMPAT #if defined(__ANDROID_API__) && __ANDROID_API__ <= 24 /* Bionic at least up to version 24 has no glob() */ @@ -13402,10 +13404,10 @@ letcmd(int argc UNUSED_PARAM, char **argv) * -p PROMPT Display PROMPT on stderr (if input is from tty) * -t SECONDS Timeout after SECONDS (tty or pipe only) * -u FD Read from given FD instead of fd 0 + * -d DELIM End on DELIM char, not newline * This uses unbuffered input, which may be avoidable in some cases. * TODO: bash also has: * -a ARRAY Read into array[0],[1],etc - * -d DELIM End on DELIM char, not newline * -e Use line editing (tty only) */ static int FAST_FUNC @@ -13415,11 +13417,12 @@ readcmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM) char *opt_p = NULL; char *opt_t = NULL; char *opt_u = NULL; + char *opt_d = NULL; /* optimized out if !BASH */ int read_flags = 0; const char *r; int i; - while ((i = nextopt("p:u:rt:n:s")) != '\0') { + while ((i = nextopt("p:u:rt:n:sd:")) != '\0') { switch (i) { case 'p': opt_p = optionarg; @@ -13439,6 +13442,11 @@ readcmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM) case 'u': opt_u = optionarg; break; +#if BASH_READ_D + case 'd': + opt_d = optionarg; + break; +#endif default: break; } @@ -13456,7 +13464,8 @@ readcmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM) opt_n, opt_p, opt_t, - opt_u + opt_u, + opt_d ); INT_ON; diff --git a/shell/shell_common.c b/shell/shell_common.c index a9f8d8413..2db8ea3e2 100644 --- a/shell/shell_common.c +++ b/shell/shell_common.c @@ -54,7 +54,8 @@ shell_builtin_read(void FAST_FUNC (*setvar)(const char *name, const char *val), const char *opt_n, const char *opt_p, const char *opt_t, - const char *opt_u + const char *opt_u, + const char *opt_d ) { struct pollfd pfd[1]; @@ -237,14 +238,17 @@ shell_builtin_read(void FAST_FUNC (*setvar)(const char *name, const char *val), continue; } } - if (c == '\n') + if (opt_d) { + if (c == *opt_d) + break; + } else if (c == '\n') break; /* $IFS splitting. NOT done if we run "read" * without variable names (bash compat). * Thus, "read" and "read REPLY" are not the same. */ - if (argv[0]) { + if (!opt_d && argv[0]) { /* http://www.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_06_05 */ const char *is_ifs = strchr(ifs, c); if (startword && is_ifs) { diff --git a/shell/shell_common.h b/shell/shell_common.h index a82535c86..1b79bffca 100644 --- a/shell/shell_common.h +++ b/shell/shell_common.h @@ -42,7 +42,8 @@ shell_builtin_read(void FAST_FUNC (*setvar)(const char *name, const char *val), const char *opt_n, const char *opt_p, const char *opt_t, - const char *opt_u + const char *opt_u, + const char *opt_d ); int FAST_FUNC |