[PATCH] ash/hush: implement -d DELIM option for `read`

2017-08-07 Thread Johannes Schindelin
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 ` 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.

Signed-off-by: Johannes Schindelin 
---
Published-As: 
https://github.com/dscho/busybox-w32/releases/tag/busybox-read-d-v1
Fetch-It-Via: git fetch https://github.com/dscho/busybox-w32 busybox-read-d-v1
 shell/ash.c  | 11 ---
 shell/hush.c |  7 +--
 shell/shell_common.c | 10 +++---
 shell/shell_common.h |  3 ++-
 4 files changed, 22 insertions(+), 9 deletions(-)

diff --git a/shell/ash.c b/shell/ash.c
index e8f3ed26b..b4f6dc3df 100644
--- a/shell/ash.c
+++ b/shell/ash.c
@@ -13402,10 +13402,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 DELIMEnd on DELIM char, not newline
  * This uses unbuffered input, which may be avoidable in some cases.
  * TODO: bash also has:
  *  -a ARRAYRead into array[0],[1],etc
- *  -d DELIMEnd on DELIM char, not newline
  *  -e  Use line editing (tty only)
  */
 static int FAST_FUNC
@@ -13415,11 +13415,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;
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 +13440,9 @@ readcmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
case 'u':
opt_u = optionarg;
break;
+   case 'd':
+   opt_d = optionarg;
+   break;
default:
break;
}
@@ -13456,7 +13460,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/hush.c b/shell/hush.c
index bb80f422c..efa518a89 100644
--- a/shell/hush.c
+++ b/shell/hush.c
@@ -9434,13 +9434,15 @@ static int FAST_FUNC builtin_read(char **argv)
char *opt_p = NULL;
char *opt_t = NULL;
char *opt_u = NULL;
+   char *opt_d = NULL;
const char *ifs;
int read_flags;
 
/* "!": do not abort on errors.
 * 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, "!srn:p:t:u:d:", &opt_n, &opt_p, &opt_t,
+   &opt_u, &opt_d);
if (read_flags == (uint32_t)-1)
return EXIT_FAILURE;
argv += optind;
@@ -9454,7 +9456,8 @@ static int FAST_FUNC builtin_read(char **argv)
opt_n,
opt_p,
opt_t,
-   opt_u
+   opt_u,
+   opt_d
);
 
if ((uintptr_t)r == 1 && errno == EINTR) {
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..1b79bf

Re: [PATCH] ash/hush: implement -d DELIM option for `read`

2017-08-07 Thread Kang-Che Sung
On Mon, Aug 7, 2017 at 6:18 PM, Johannes Schindelin
 wrote:
> 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 ` 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.
>
> Signed-off-by: Johannes Schindelin 

Can you wrap the change within a macro conditional like #if BASH_READ_D ?
___
busybox mailing list
busybox@busybox.net
http://lists.busybox.net/mailman/listinfo/busybox


Re: [PATCH] ash/hush: implement -d DELIM option for `read`

2017-08-08 Thread Johannes Schindelin
Hi,

On Tue, 8 Aug 2017, Kang-Che Sung wrote:

> On Mon, Aug 7, 2017 at 6:18 PM, Johannes Schindelin
>  wrote:
> > 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 ` 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.
> >
> > Signed-off-by: Johannes Schindelin 
> 
> Can you wrap the change within a macro conditional like #if BASH_READ_D ?

I can! And I did! It made the patch a little less readable, though.

Ciao,
Johannes
___
busybox mailing list
busybox@busybox.net
http://lists.busybox.net/mailman/listinfo/busybox