This commit removes some uses of gdb::argv_vec from GDB.
The gdb::argv_vec class exists in part due to our need to convert from
one container type to another in a few places, and I think by using
templates we can push this conversion down into
gdbsupport/common-inferior.{cc,h} and remove the conversion logic from
higher level code in GDB. This should make core GDB simpler.
For examples of this simplification, see python/py-inferior.c,
remote.c, and unittests/remote-arg-selftests.c, where this commit has
allowed for the removal of some code that only exists in order to
convert the container type.
Ideally I'd like to see all uses of gdb::argv_vec removed, but I'm
still not sure about the use in nat/fork-inferior.c, I think its use
there might be the best solution, so for now at least, I have no plans
to touch that code.
There should be no user visible changes after this commit.
Approved-By: Tom Tromey <tom@tromey.com>
return m_terminal;
}
-/* See inferior.h. */
-
-void
-inferior::set_args (gdb::array_view<char * const> args,
- bool escape_shell_char)
-{
- set_args (construct_inferior_arguments (args, escape_shell_char));
-}
-
void
inferior::set_arch (gdbarch *arch)
{
#include "displaced-stepping.h"
#include "gdbsupport/unordered_map.h"
+#include "gdbsupport/common-inferior.h"
struct infcall_suspend_state;
struct infcall_control_state;
ESCAPE_SHELL_CHAR is true all special shell characters in ARGS are
escaped, When false only the characters that GDB sees as special will
be escaped. See construct_inferior_arguments for more details. */
- void set_args (gdb::array_view<char * const> args, bool escape_shell_char);
+ template<typename T>
+ void set_args (gdb::array_view<T const> args, bool escape_shell_char)
+ {
+ this->set_args (construct_inferior_arguments (args, escape_shell_char));
+ }
/* Get the argument string to use when running this inferior.
return -1;
args.push_back (std::move (str));
}
- std::vector<char *> argvec;
- for (const auto &arg : args)
- argvec.push_back (arg.get ());
- gdb::array_view<char * const> view (argvec.data (), argvec.size ());
- inf->inferior->set_args (view, true);
+ gdb::array_view<gdb::unique_xmalloc_ptr<char> const> args_view (args);
+ inf->inferior->set_args (args_view, true);
}
else
{
#include "gdbsupport/selftest.h"
#include "cli/cli-style.h"
#include "gdbsupport/remote-args.h"
-#include "gdbsupport/gdb_argv_vec.h"
#include "finish-thread-state.h"
/* The remote target. */
for (const std::string &a : split_args)
gdb_printf (" (%s)\n", a.c_str ());
- gdb::argv_vec tmp_split_args;
- for (const std::string &a : split_args)
- tmp_split_args.emplace_back (xstrdup (a.c_str ()));
-
- std::string joined_args = gdb::remote_args::join (tmp_split_args.get ());
+ std::string joined_args = gdb::remote_args::join (split_args);
gdb_printf ("Output (%s)\n", joined_args.c_str ());
std::vector<std::string> resplit = gdb::remote_args::split (joined_args);
- tmp_split_args.clear ();
- for (const std::string &a : resplit)
- tmp_split_args.emplace_back (xstrdup (a.c_str ()));
-
- std::string rejoined = gdb::remote_args::join (tmp_split_args.get ());
+ std::string rejoined = gdb::remote_args::join (resplit);
if (joined_args != rejoined || split_args != resplit)
{
#include "gdbsupport/buildargv.h"
#include "gdbsupport/common-inferior.h"
#include "gdbsupport/remote-args.h"
-#include "gdbsupport/gdb_argv_vec.h"
namespace selftests {
namespace remote_args_tests {
}
/* Now join the arguments. */
- gdb::argv_vec split_args_c_str;
- for (const std::string &s : split_args)
- split_args_c_str.push_back (xstrdup (s.c_str ()));
std::string joined_args
- = gdb::remote_args::join (split_args_c_str.get ());
+ = gdb::remote_args::join (split_args);
if (run_verbose ())
debug_printf ("Joined (%s), expected (%s)\n",
#include "gdbsupport/gdb_select.h"
#include "gdbsupport/scoped_restore.h"
#include "gdbsupport/search.h"
-#include "gdbsupport/gdb_argv_vec.h"
#include "gdbsupport/remote-args.h"
#include <getopt.h>
{
client_state &cs = get_client_state ();
char *p, *next_p;
- gdb::argv_vec new_argv;
+ std::vector<gdb::unique_xmalloc_ptr<char>> new_argv;
gdb::unique_xmalloc_ptr<char> new_program_name;
int i;
else if (p == next_p)
{
/* Empty argument. */
- new_argv.push_back (xstrdup (""));
+ new_argv.push_back (make_unique_xstrdup (""));
}
else
{
if (i == 0)
new_program_name = std::move (arg);
else
- new_argv.push_back (arg.release ());
+ new_argv.push_back (std::move (arg));
}
if (*next_p == '\0')
break;
if (cs.single_inferior_argument)
{
- if (new_argv.get ().size () > 1)
+ if (new_argv.size () > 1)
{
write_enn (own_buf);
return;
}
- else if (new_argv.get ().size () == 1)
- program_args = std::string (new_argv.get ()[0]);
+ else if (new_argv.size () == 1)
+ program_args = std::string (new_argv[0].get ());
else
program_args.clear ();
}
else
- program_args = gdb::remote_args::join (new_argv.get ());
+ program_args = gdb::remote_args::join (new_argv);
try
{
error (_("No program to debug"));
int n = argc - (next_arg - argv);
- program_args
- = construct_inferior_arguments ({&next_arg[1], &next_arg[n]},
- escape_args);
+ gdb::array_view<char * const> args_view (&next_arg[1], &next_arg[n]);
+ program_args = construct_inferior_arguments (args_view, escape_args);
/* Wait till we are at first instruction in program. */
target_create_inferior (program_path.get (), program_args);
return escape_characters (arg, special);
}
-/* See common-inferior.h. */
+/* Template function that converts a T to a 'const char *'. */
+
+template<typename T> const char * to_char_ptr (T &arg);
+
+/* A no-op implementation that takes a 'const char *'. */
+
+template<>
+const char *
+to_char_ptr (char * const &arg)
+{
+ return arg;
+}
+
+/* An implementation that gets a 'const char *' from a
+ gdb::unique_xmalloc_ptr<char> object. */
+
+template<>
+const char *
+to_char_ptr (const gdb::unique_xmalloc_ptr<char> &arg)
+{
+ return arg.get ();
+}
+
+/* An implementation that gets a 'const char *' from a std::string. */
+
+template<>
+const char *
+to_char_ptr (const std::string &arg)
+{
+ return arg.c_str ();
+}
+
+/* See gdbsupport/common-inferior.h. */
+template<typename T>
std::string
-construct_inferior_arguments (gdb::array_view<char * const> argv,
+construct_inferior_arguments (gdb::array_view<T const> argv,
bool escape_shell_char)
{
/* Select the desired escape function. */
std::string result;
- for (const char *a : argv)
+ for (const T &a : argv)
{
if (!result.empty ())
result += " ";
- result += escape_func (a);
+ result += escape_func (to_char_ptr (a));
}
return result;
}
+
+/* Instantiate for T = 'gdb::unique_xmalloc_ptr<char>'. */
+
+template
+std::string
+construct_inferior_arguments
+ (gdb::array_view<gdb::unique_xmalloc_ptr<char> const> argv,
+ bool escape_shell_char);
+
+/* Instantiate for T = 'char *'. */
+
+template
+std::string
+construct_inferior_arguments (gdb::array_view<char * const> argv,
+ bool escape_shell_char);
+
+/* Instantiate for T = 'std::string'. */
+
+template
+std::string
+construct_inferior_arguments (gdb::array_view<std::string const> argv,
+ bool escape_shell_char);
whitespace character between each element. When ESCAPE_SHELL_CHAR is
true then any special shell characters in elements of ARGV will be
escaped. When ESCAPE_SHELL_CHAR is false only the characters that GDB
- sees as special (quotes and whitespace) are escaped. */
+ sees as special (quotes and whitespace) are escaped.
+
+ This function is instantiated for T as 'gdb::unique_xmalloc_ptr<char>',
+ 'char *', and 'std::string'. */
+
+template<typename T>
extern std::string
-construct_inferior_arguments (gdb::array_view<char * const> argv,
- bool escape_shell_char);
+construct_inferior_arguments
+ (gdb::array_view<T const> argv, bool escape_shell_char);
#endif /* GDBSUPPORT_COMMON_INFERIOR_H */
return results;
}
-
-/* See remote-args.h. */
-
-std::string
-gdb::remote_args::join (const std::vector<char *> &args)
-{
- return construct_inferior_arguments (args, true);
-}
#ifndef GDBSUPPORT_REMOTE_ARGS_H
#define GDBSUPPORT_REMOTE_ARGS_H
+#include "gdbsupport/common-inferior.h"
+
/* The functions declared here are used when passing inferior arguments
from GDB to gdbserver.
argument of 'a b' (without the single quotes). When this argument is
passed through ::join we will get back the string 'a\ b' (without the
single quotes), that is, we choose to escape the white space, rather
- than wrap the argument in quotes. */
-extern std::string join (const std::vector<char *> &args);
+ than wrap the argument in quotes.
+
+ This function depends on construct_inferior_arguments, which is
+ instantiated for the string types used within GDB, 'char *',
+ 'std::string', and 'gdb::unique_xmalloc_ptr<char>'. */
+
+template<typename T>
+inline std::string
+join (const std::vector<T> &args)
+{
+ return construct_inferior_arguments (gdb::array_view<const T> (args), true);
+}
} /* namespace remote_args */