diff options
Diffstat (limited to 'gdbsupport')
-rw-r--r-- | gdbsupport/ChangeLog | 5 | ||||
-rw-r--r-- | gdbsupport/common-inferior.cc | 122 | ||||
-rw-r--r-- | gdbsupport/common-inferior.h | 4 |
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 */ |