* string. Note that we treat benign UTF-8 characters as needing
* escaping too, but that should be OK. */
+ if (FLAGS_SET(flags, SHELL_ESCAPE_EMPTY) && isempty(s))
+ return strdup("\"\""); /* We don't use $'' here in the POSIX mode. "" is fine too. */
+
for (p = s; *p; p++)
if (*p <= ' ' ||
*p >= 127 ||
* Tabs and newlines are escaped. */
SHELL_ESCAPE_POSIX = 1 << 1, /* Use POSIX shell escape syntax (a string enclosed in $'') instead of plain quotes. */
+ SHELL_ESCAPE_EMPTY = 1 << 2, /* Format empty arguments as "". */
} ShellEscapeFlags;
char* cescape(const char *s);
static void test_shell_maybe_quote(void) {
test_shell_maybe_quote_one("", 0, "");
+ test_shell_maybe_quote_one("", SHELL_ESCAPE_EMPTY, "\"\"");
test_shell_maybe_quote_one("", SHELL_ESCAPE_POSIX, "");
+ test_shell_maybe_quote_one("", SHELL_ESCAPE_POSIX | SHELL_ESCAPE_EMPTY, "\"\"");
test_shell_maybe_quote_one("\\", 0, "\"\\\\\"");
test_shell_maybe_quote_one("\\", SHELL_ESCAPE_POSIX, "$'\\\\'");
test_shell_maybe_quote_one("\"", 0, "\"\\\"\"");
test_shell_maybe_quote_one("foo \"bar\" waldo", 0, "\"foo \\\"bar\\\" waldo\"");
test_shell_maybe_quote_one("foo \"bar\" waldo", SHELL_ESCAPE_POSIX, "$'foo \"bar\" waldo'");
test_shell_maybe_quote_one("foo$bar", 0, "\"foo\\$bar\"");
+ test_shell_maybe_quote_one("foo$bar", SHELL_ESCAPE_EMPTY, "\"foo\\$bar\"");
test_shell_maybe_quote_one("foo$bar", SHELL_ESCAPE_POSIX, "$'foo$bar'");
+ test_shell_maybe_quote_one("foo$bar", SHELL_ESCAPE_POSIX | SHELL_ESCAPE_EMPTY, "$'foo$bar'");
/* Note that current users disallow control characters, so this "test"
* is here merely to establish current behaviour. If control characters