hare

The Hare programming language
git clone https://git.torresjrjr.com/hare.git
Log | Files | Refs | README | LICENSE

commit c80c71f920b0e94370338341fef35b7f6fd4f07c
parent 732383144a66c247b6c732b1ce7f46342d340019
Author: Sebastian <sebastian@sebsite.pw>
Date:   Thu, 28 Apr 2022 17:26:22 -0400

shlex: return number of bytes written for quote

Fixes: https://todo.sr.ht/~sircmpwn/hare/619
Signed-off-by: Sebastian <sebastian@sebsite.pw>

Diffstat:
Mshlex/+test.ha | 24+++++++++++++-----------
Mshlex/escape.ha | 17++++++++---------
2 files changed, 21 insertions(+), 20 deletions(-)

diff --git a/shlex/+test.ha b/shlex/+test.ha @@ -1,6 +1,8 @@ // License: MPL-2.0 // (c) 2021 Alexey Yerin <yyp@disroot.org> +use io; use strings; +use strio; @test fn split() void = { const s = split(`hello\ world`)!; @@ -61,16 +63,16 @@ use strings; assert(split(`unterminated\ backslash \`) is syntaxerr); }; -@test fn quote() void = { - const bare = quotestr(`hello`); - defer free(bare); - assert(bare == `hello`); - - const spaces = quotestr(`hello world`); - defer free(spaces); - assert(spaces == `"hello world"`); +fn testquote(sink: *strio::stream, s: str, expected: str) void = { + assert(quote(sink, s)! == len(expected)); + assert(strio::string(sink) == expected); + strio::reset(sink); +}; - const quotes = quotestr(`'hello' "world"`); - defer free(quotes); - assert(quotes == `"'hello' "'"'"world"'"'""`); +@test fn quote() void = { + const sink = strio::dynamic(); + defer io::close(&sink)!; + testquote(&sink, `hello`, `hello`); + testquote(&sink, `hello world`, `"hello world"`); + testquote(&sink, `'hello' "world"`, `"'hello' "'"'"world"'"'""`); }; diff --git a/shlex/escape.ha b/shlex/escape.ha @@ -28,17 +28,15 @@ fn is_safe(s: str) bool = { }; // Quotes a shell string and writes it to the provided I/O handle. -export fn quote(sink: io::handle, s: str) (void | io::error) = { +export fn quote(sink: io::handle, s: str) (size | io::error) = { if (len(s) == 0) { - io::write(sink, strings::toutf8(`''`))?; - return; + return io::writeall(sink, strings::toutf8(`''`))?; }; if (is_safe(s)) { - io::write(sink, strings::toutf8(s))?; - return; + return io::writeall(sink, strings::toutf8(s))?; }; - io::write(sink, ['"'])?; + let z = io::writeall(sink, ['"'])?; const iter = strings::iter(s); for (true) { @@ -50,13 +48,14 @@ export fn quote(sink: io::handle, s: str) (void | io::error) = { }; if (rn == '"') { - io::write(sink, strings::toutf8(`"'"'"`))?; + z += io::writeall(sink, strings::toutf8(`"'"'"`))?; } else { - io::write(sink, utf8::encoderune(rn))?; + z += io::writeall(sink, utf8::encoderune(rn))?; }; }; - io::write(sink, ['"'])?; + z += io::writeall(sink, ['"'])?; + return z; }; // Quotes a shell string and returns a new string. The caller must free the