~sircmpwn/hare

141cf68540cd77db87475942c5d979e07a97d00a — Sebastian 2 months ago fd7addb
wordexp: correctly handle string containing only whitespace

Turns out the "x" hack was necessary after all.

Signed-off-by: Sebastian <sebastian@sebsite.pw>
2 files changed, 9 insertions(+), 6 deletions(-)

M wordexp/+test.ha
M wordexp/wordexp.ha
M wordexp/+test.ha => wordexp/+test.ha +1 -0
@@ 21,6 21,7 @@ fn streq(a: []str, b: []str) bool = {
	os::unsetenv("UNSET")!;
	static const cases: [_](str, []str) = [
		(``, []),
		(" \t\n", []),
		(`hello world`, ["hello", "world"]),
		(`hello $TESTVAR`, ["hello", "test", "value"]),
		(`hello "$TESTVAR"`, ["hello", "test value"]),

M wordexp/wordexp.ha => wordexp/wordexp.ha +8 -6
@@ 28,16 28,12 @@ export type flag = enum uint {
// Pass the return value to [[strings::freeall]] to free resources associated
// with the return value.
export fn wordexp(s: str, flags: flag) ([]str | error) = {
	if (s == "") {
		// Special case
		return [];
	};

	const (rd, wr) = exec::pipe();

	// "x" is added to handle the list of expanded words being empty
	const cmd = exec::cmd("/bin/sh",
		if (flags & flag::UNDEF != 0) "-uc" else "-c",
		`eval "printf %s\\\\0 $1"`, "sh", s)!;
		`eval "printf %s\\\\0 x $1"`, "sh", s)!;
	exec::unsetenv(&cmd, "IFS")!;
	exec::addfile(&cmd, os::stdout_file, wr);
	if (flags & flag::SHOWERR == 0) {


@@ 49,6 45,12 @@ export fn wordexp(s: str, flags: flag) ([]str | error) = {
	const scan = bufio::newscanner(rd, types::SIZE_MAX);
	defer bufio::finish(&scan);

	match (bufio::scan_string(&scan, "\0")?) {
	case io::EOF =>
		return sh_error;
	case => void; // Discard the first "x" argument
	};

	let words: []str = [];
	for (true) {
		match (bufio::scan_string(&scan, "\0")?) {