hush: 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.

We already support this in ash, let's add it to hush, too.

function                                             old     new   delta
builtin_read                                         263     284     +21
.rodata                                           163587  163589      +2
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 2/0 up/down: 23/0)               Total: 23 bytes

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
Denys Vlasenko 2017-08-09 13:52:36 +02:00
parent 3bef5d89b0
commit 1f41c885fc

View File

@ -352,6 +352,7 @@
#define BASH_SOURCE ENABLE_HUSH_BASH_COMPAT #define BASH_SOURCE ENABLE_HUSH_BASH_COMPAT
#define BASH_HOSTNAME_VAR ENABLE_HUSH_BASH_COMPAT #define BASH_HOSTNAME_VAR ENABLE_HUSH_BASH_COMPAT
#define BASH_TEST2 (ENABLE_HUSH_BASH_COMPAT && ENABLE_HUSH_TEST) #define BASH_TEST2 (ENABLE_HUSH_BASH_COMPAT && ENABLE_HUSH_TEST)
#define BASH_READ_D ENABLE_HUSH_BASH_COMPAT
/* Build knobs */ /* Build knobs */
@ -9434,13 +9435,20 @@ static int FAST_FUNC builtin_read(char **argv)
char *opt_p = NULL; char *opt_p = NULL;
char *opt_t = NULL; char *opt_t = NULL;
char *opt_u = NULL; char *opt_u = NULL;
char *opt_d = NULL; /* optimized out if !BASH */
const char *ifs; const char *ifs;
int read_flags; int read_flags;
/* "!": do not abort on errors. /* "!": do not abort on errors.
* Option string must start with "sr" to match BUILTIN_READ_xxx * Option string must start with "sr" to match BUILTIN_READ_xxx
*/ */
read_flags = getopt32(argv, "!srn:p:t:u:", &opt_n, &opt_p, &opt_t, &opt_u); read_flags = getopt32(argv,
#if BASH_READ_D
"!srn:p:t:u:d:", &opt_n, &opt_p, &opt_t, &opt_u, &opt_d
#else
"!srn:p:t:u:", &opt_n, &opt_p, &opt_t, &opt_u
#endif
);
if (read_flags == (uint32_t)-1) if (read_flags == (uint32_t)-1)
return EXIT_FAILURE; return EXIT_FAILURE;
argv += optind; argv += optind;
@ -9454,7 +9462,8 @@ static int FAST_FUNC builtin_read(char **argv)
opt_n, opt_n,
opt_p, opt_p,
opt_t, opt_t,
opt_u opt_u,
opt_d
); );
if ((uintptr_t)r == 1 && errno == EINTR) { if ((uintptr_t)r == 1 && errno == EINTR) {