This thread contains a patchset. You're looking at the original emails,
but you may wish to use the patch review UI.
Review patch
7
4
[PATCH hautils v3] yes: new command
hi,
v3 simplies some logic in the if statement
---
Makefile | 4 +++ -
yes.ha | 22 ++++++++++++++++++++++
2 files changed, 25 insertions(+), 1 deletion(-)
create mode 100644 yes.ha
diff --git a/Makefile b/Makefile
index c568580..298db4b 100644
--- a/Makefile
+++ b/Makefile
@@ -18,7 +18,8 @@ utils=\
true \
uname \
uniq \
- wc
+ wc \
+ yes
all: $(utils)
@@ -46,3 +47,4 @@ true: true.ha
uname: uname.ha main/main.ha
uniq: uniq.ha main/main.ha
wc: wc.ha main/main.ha
+ yes: yes.ha main/main.ha
diff --git a/yes.ha b/yes.ha
new file mode 100644
index 0000000..957bbc0
--- /dev/null
+++ b/yes.ha
@@ -0,0 +1,22 @@
+ use fmt;
+ use getopt;
+ use os;
+ use main;
+
+ export fn utilmain() (main::error | void) = {
+ const help: []getopt::help = [
+ "output string repeatedly",
+ "<string>",
+ ];
+ const cmd = getopt::parse(os::args, help...);
+ defer getopt::finish(&cmd);
+ if (len(cmd.args) > 1) {
+ getopt::printhelp(os::stderr, os::args[0], help);
+ os::exit(1);
+ };
+ const s = if (len(cmd.args) == 1) cmd.args[0] else "y";
+ for (true) {
+ fmt::printfln(s)!;
+ };
+ return void;
+ };
--
2.39.1
On Tue Feb 21, 2023 at 8:32 AM EST, jgart wrote:
> hi,
>
> v3 simplies some logic in the if statement
>
> ---
> (snip)
> diff --git a/yes.ha b/yes.ha
> new file mode 100644
> index 0000000..957bbc0
> --- /dev/null
> +++ b/yes.ha
> @@ -0,0 +1,22 @@
> +use fmt;
> +use getopt;
> +use os;
> +use main;
> +
> +export fn utilmain() (main::error | void) = {
> + const help: []getopt::help = [
> + "output string repeatedly",
> + "<string>",
> + ];
> + const cmd = getopt::parse(os::args, help...);
> + defer getopt::finish(&cmd);
> + if (len(cmd.args) > 1) {
> + getopt::printhelp(os::stderr, os::args[0], help);
> + os::exit(1);
> + };
> + const s = if (len(cmd.args) == 1) cmd.args[0] else "y";
> + for (true) {
> + fmt::printfln(s)!;
fmt::printfln should not be used, because s is not a format string:
master$ ./yes '{}'
Abort: /usr/src/hare/stdlib/fmt/fmt.ha:220:31: Not enough parameters given
Aborted (core dumped)
You should use fmt::println instead.
> + };
> + return void;
> +};
> --
> 2.39.1
Hi Sebastian,
> You should use fmt::println instead.
See v4 where this is fixed. I just saw your message now but someone else had also pointed this out to me offlist.
Thank you for the review!
all best,
jgart
On 2023-02-21 14:32 UTC, jgart wrote:
> hi,
>
> v3 simplies some logic in the if statement
>
> ---
> Makefile | 4 +++-
> yes.ha | 22 ++++++++++++++++++++++
> 2 files changed, 25 insertions(+), 1 deletion(-)
> create mode 100644 yes.ha
>
> diff --git a/Makefile b/Makefile
> index c568580..298db4b 100644
> --- a/Makefile
> +++ b/Makefile
> @@ -18,7 +18,8 @@ utils=\
> true \
> uname \
> uniq \
> - wc
> + wc \
> + yes
>
> all: $(utils)
>
> @@ -46,3 +47,4 @@ true: true.ha
> uname: uname.ha main/main.ha
> uniq: uniq.ha main/main.ha
> wc: wc.ha main/main.ha
> +yes: yes.ha main/main.ha
> diff --git a/yes.ha b/yes.ha
> new file mode 100644
> index 0000000..957bbc0
> --- /dev/null
> +++ b/yes.ha
> @@ -0,0 +1,22 @@
> +use fmt;
> +use getopt;
> +use os;
> +use main;
> +
> +export fn utilmain() (main::error | void) = {
> + const help: []getopt::help = [
> + "output string repeatedly",
> + "<string>",
> + ];
> + const cmd = getopt::parse(os::args, help...);
> + defer getopt::finish(&cmd);
> + if (len(cmd.args) > 1) {
> + getopt::printhelp(os::stderr, os::args[0], help);
> + os::exit(1);
> + };
> + const s = if (len(cmd.args) == 1) cmd.args[0] else "y";
> + for (true) {
> + fmt::printfln(s)!;
> + };
> + return void;
> +};
> --
> 2.39.1
I don't know if performance parity with coreutils is a goal for hautils
in general or for `yes` is particular, but they are several orders of
magnitude apart:
$ timeout 5 /usr/bin/yes | pv -ba >/dev/null
22.8GiB [4.56GiB/s]
$ timeout 5 ./yes | pv -ba >/dev/null
11.2MiB [2.24MiB/s]
coreutils' `yes` does buffered IO:
$ strace /usr/bin/yes >/dev/null
...
write(1, "y\ny\ny\ny\ny\ny\ny\ny\ny\ny\ny\ny\ny\ny\ny\ny\n"..., 8192) = 8192
write(1, "y\ny\ny\ny\ny\ny\ny\ny\ny\ny\ny\ny\ny\ny\ny\ny\n"..., 8192) = 8192
write(1, "y\ny\ny\ny\ny\ny\ny\ny\ny\ny\ny\ny\ny\ny\ny\ny\n"..., 8192) = 8192
write(1, "y\ny\ny\ny\ny\ny\ny\ny\ny\ny\ny\ny\ny\ny\ny\ny\n"..., 8192) = 8192
...
I think they pre fill a buffer and just call write(2) repeatedly with
it. If performance is a consideration in this case, it shouldn't be
that hard to do something similar.
The performance of yes(1) is not of any conseqeunce. Simplicity is the
word.
On 2023-02-21 19:59 UTC, Drew DeVault wrote:
> The performance of yes(1) is not of any conseqeunce. Simplicity is the
> word.
Yes, it makes sense. Just wondering if someone could have some use-case
expecting a performant yes(1). Not my case, though.
It seems that hautils might lean more in the spirit/aesthetics of sbase but I may be wrong:
https://github.com/michaelforney/sbase
Thanks for the all the code reviews. Much appreciated!
--
jgart
Skipping this on the basis that it's not POSIX.