bool startup_with_shell = true;
-/* See common-inferior.h. */
+/* Escape characters in ARG and return an updated string. The string
+ SPECIAL contains the set of characters that must be escaped. SPECIAL
+ must not be nullptr, and it is assumed that SPECIAL contains the newline
+ '\n' character. It is assumed that ARG is not nullptr, but ARG can
+ be the empty string. */
-std::string
-construct_inferior_arguments (gdb::array_view<char * const> argv)
+static std::string
+escape_characters (const char *arg, const char *special)
{
+ gdb_assert (special != nullptr);
+ gdb_assert (arg != nullptr);
+
std::string result;
#ifdef __MINGW32__
- /* This holds all the characters considered special to the
- Windows shells. */
- static const char special[] = "\"!&*|[]{}<>?`~^=;, \t\n";
static const char quote = '"';
#else
- /* This holds all the characters considered special to the
- typical Unix shells. We include `^' because the SunOS
- /bin/sh treats it as a synonym for `|'. */
- static const char special[] = "\"!#$&*()\\|[]{}<>?'`~^; \t\n";
static const char quote = '\'';
#endif
- for (int i = 0; i < argv.size (); ++i)
+
+ /* Need to handle empty arguments specially. */
+ if (arg[0] == '\0')
{
- if (i > 0)
- result += ' ';
+ result += quote;
+ result += quote;
+ }
+ /* The special character handling code here assumes that if SPECIAL is
+ not nullptr, then SPECIAL will contain '\n'. This is true for all our
+ current usages, but if this ever changes in the future the following
+ might need reworking. */
+ else
+ {
+#ifdef __MINGW32__
+ bool quoted = false;
- /* Need to handle empty arguments specially. */
- if (argv[i][0] == '\0')
+ if (strpbrk (argv[i], special))
{
- result += quote;
+ quoted = true;
result += quote;
}
- else
+#endif
+ for (const char *cp = arg; *cp; ++cp)
{
-#ifdef __MINGW32__
- bool quoted = false;
-
- if (strpbrk (argv[i], special))
+ if (*cp == '\n')
{
- quoted = true;
+ /* A newline cannot be quoted with a backslash (it just
+ disappears), only by putting it inside quotes. */
+ result += quote;
+ result += '\n';
result += quote;
}
-#endif
- for (char *cp = argv[i]; *cp != '\0'; ++cp)
+ else
{
- if (*cp == '\n')
- {
- /* A newline cannot be quoted with a backslash (it
- just disappears), only by putting it inside
- quotes. */
- result += quote;
- result += '\n';
- result += quote;
- }
- else
- {
#ifdef __MINGW32__
- if (*cp == quote)
+ if (*cp == quote)
#else
- if (strchr (special, *cp) != NULL)
+ if (strchr (special, *cp) != nullptr)
#endif
- result += '\\';
- result += *cp;
- }
+ result += '\\';
+ result += *cp;
}
+ }
#ifdef __MINGW32__
- if (quoted)
- result += quote;
+ if (quoted)
+ result += quote;
#endif
- }
+ }
+
+ return result;
+}
+
+/* Return a version of ARG that has special shell characters escaped. */
+
+static std::string
+escape_shell_characters (const char *arg)
+{
+#ifdef __MINGW32__
+ /* This holds all the characters considered special to the
+ Windows shells. */
+ static const char special[] = "\"!&*|[]{}<>?`~^=;, \t\n";
+#else
+ /* This holds all the characters considered special to the
+ typical Unix shells. We include `^' because the SunOS
+ /bin/sh treats it as a synonym for `|'. */
+ static const char special[] = "\"!#$&*()\\|[]{}<>?'`~^; \t\n";
+#endif
+
+ return escape_characters (arg, special);
+}
+
+/* Return a version of ARG that has quote characters and white space
+ characters escaped. These are the characters that GDB sees as special
+ when splitting a string into separate arguments. */
+
+static std::string
+escape_gdb_characters (const char * arg)
+{
+#ifdef __MINGW32__
+ static const char special[] = "\" \t\n";
+#else
+ static const char special[] = "\"' \t\n";
+#endif
+
+ return escape_characters (arg, special);
+}
+
+/* See common-inferior.h. */
+
+std::string
+construct_inferior_arguments (gdb::array_view<char * const> argv,
+ bool escape_shell_char)
+{
+ /* Select the desired escape function. */
+ const auto escape_func = (escape_shell_char
+ ? escape_shell_characters
+ : escape_gdb_characters);
+
+ std::string result;
+
+ for (const char *a : argv)
+ {
+ if (!result.empty ())
+ result += " ";
+
+ result += escape_func (a);
}
return result;
the target is started up with a shell. */
extern bool startup_with_shell;
-/* Compute command-line string given argument vector. This does the
- same shell processing as fork_inferior. */
+/* Combine elements of ARGV into a single string, placing a single
+ whitespace character between each element. When ESCAPE_SHELL_CHAR is
+ true then any special shell characters in elemets of ARGV will be
+ escaped. When ESCAPE_SHELL_CHAR is false only the characters that GDB
+ sees as special (quotes and whitespace) are escaped. */
extern std::string
-construct_inferior_arguments (gdb::array_view<char * const>);
+construct_inferior_arguments (gdb::array_view<char * const> argv,
+ bool escape_shell_char);
#endif /* GDBSUPPORT_COMMON_INFERIOR_H */