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