aboutsummaryrefslogtreecommitdiff
path: root/gdbsupport
diff options
context:
space:
mode:
Diffstat (limited to 'gdbsupport')
-rw-r--r--gdbsupport/ChangeLog5
-rw-r--r--gdbsupport/common-inferior.cc122
-rw-r--r--gdbsupport/common-inferior.h4
3 files changed, 131 insertions, 0 deletions
diff --git a/gdbsupport/ChangeLog b/gdbsupport/ChangeLog
index e7374ab..4f72c7d 100644
--- a/gdbsupport/ChangeLog
+++ b/gdbsupport/ChangeLog
@@ -1,3 +1,8 @@
+2020-05-25 Michael Weghorn <m.weghorn@posteo.de>
+
+ * common-inferior.h, common-inferior.cc: (construct_inferior_arguments):
+ Move function here from gdb/infcmd.c, gdb/inferior.h
+
2020-05-14 Kevin Buettner <kevinb@redhat.com>
* btrace-common.h (btrace_cpu_vendor): Add CV_AMD.
diff --git a/gdbsupport/common-inferior.cc b/gdbsupport/common-inferior.cc
index ed16e89..a7d631f 100644
--- a/gdbsupport/common-inferior.cc
+++ b/gdbsupport/common-inferior.cc
@@ -24,3 +24,125 @@
/* See common-inferior.h. */
bool startup_with_shell = true;
+
+/* See common-inferior.h. */
+
+char *
+construct_inferior_arguments (int argc, char **argv)
+{
+ char *result;
+
+ /* ARGC should always be at least 1, but we double check this
+ here. This is also needed to silence -Werror-stringop
+ warnings. */
+ gdb_assert (argc > 0);
+
+ if (startup_with_shell)
+ {
+#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
+ int i;
+ int length = 0;
+ char *out, *cp;
+
+ /* We over-compute the size. It shouldn't matter. */
+ for (i = 0; i < argc; ++i)
+ length += 3 * strlen (argv[i]) + 1 + 2 * (argv[i][0] == '\0');
+
+ result = (char *) xmalloc (length);
+ out = result;
+
+ for (i = 0; i < argc; ++i)
+ {
+ if (i > 0)
+ *out++ = ' ';
+
+ /* Need to handle empty arguments specially. */
+ if (argv[i][0] == '\0')
+ {
+ *out++ = quote;
+ *out++ = quote;
+ }
+ else
+ {
+#ifdef __MINGW32__
+ int quoted = 0;
+
+ if (strpbrk (argv[i], special))
+ {
+ quoted = 1;
+ *out++ = quote;
+ }
+#endif
+ for (cp = argv[i]; *cp; ++cp)
+ {
+ if (*cp == '\n')
+ {
+ /* A newline cannot be quoted with a backslash (it
+ just disappears), only by putting it inside
+ quotes. */
+ *out++ = quote;
+ *out++ = '\n';
+ *out++ = quote;
+ }
+ else
+ {
+#ifdef __MINGW32__
+ if (*cp == quote)
+#else
+ if (strchr (special, *cp) != NULL)
+#endif
+ *out++ = '\\';
+ *out++ = *cp;
+ }
+ }
+#ifdef __MINGW32__
+ if (quoted)
+ *out++ = quote;
+#endif
+ }
+ }
+ *out = '\0';
+ }
+ else
+ {
+ /* In this case we can't handle arguments that contain spaces,
+ tabs, or newlines -- see breakup_args(). */
+ int i;
+ int length = 0;
+
+ for (i = 0; i < argc; ++i)
+ {
+ char *cp = strchr (argv[i], ' ');
+ if (cp == NULL)
+ cp = strchr (argv[i], '\t');
+ if (cp == NULL)
+ cp = strchr (argv[i], '\n');
+ if (cp != NULL)
+ error (_("can't handle command-line "
+ "argument containing whitespace"));
+ length += strlen (argv[i]) + 1;
+ }
+
+ result = (char *) xmalloc (length);
+ result[0] = '\0';
+ for (i = 0; i < argc; ++i)
+ {
+ if (i > 0)
+ strcat (result, " ");
+ strcat (result, argv[i]);
+ }
+ }
+
+ return result;
+}
diff --git a/gdbsupport/common-inferior.h b/gdbsupport/common-inferior.h
index 3c8e87a..ee87bc7 100644
--- a/gdbsupport/common-inferior.h
+++ b/gdbsupport/common-inferior.h
@@ -58,4 +58,8 @@ extern void set_inferior_cwd (const char *cwd);
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. */
+extern char *construct_inferior_arguments (int, char **);
+
#endif /* COMMON_COMMON_INFERIOR_H */