aboutsummaryrefslogtreecommitdiff
path: root/gdb/common
diff options
context:
space:
mode:
Diffstat (limited to 'gdb/common')
-rw-r--r--gdb/common/environ.c75
-rw-r--r--gdb/common/environ.h24
-rw-r--r--gdb/common/rsp-low.c41
-rw-r--r--gdb/common/rsp-low.h8
4 files changed, 133 insertions, 15 deletions
diff --git a/gdb/common/environ.c b/gdb/common/environ.c
index 698bda3..7753f6e 100644
--- a/gdb/common/environ.c
+++ b/gdb/common/environ.c
@@ -30,8 +30,12 @@ gdb_environ::operator= (gdb_environ &&e)
return *this;
m_environ_vector = std::move (e.m_environ_vector);
+ m_user_set_env = std::move (e.m_user_set_env);
+ m_user_unset_env = std::move (e.m_user_unset_env);
e.m_environ_vector.clear ();
e.m_environ_vector.push_back (NULL);
+ e.m_user_set_env.clear ();
+ e.m_user_unset_env.clear ();
return *this;
}
@@ -65,6 +69,8 @@ gdb_environ::clear ()
m_environ_vector.clear ();
/* Always add the NULL element. */
m_environ_vector.push_back (NULL);
+ m_user_set_env.clear ();
+ m_user_unset_env.clear ();
}
/* Helper function to check if STRING contains an environment variable
@@ -72,7 +78,7 @@ gdb_environ::clear ()
if it contains, false otherwise. */
static bool
-match_var_in_string (char *string, const char *var, size_t var_len)
+match_var_in_string (const char *string, const char *var, size_t var_len)
{
if (strncmp (string, var, var_len) == 0 && string[var_len] == '=')
return true;
@@ -99,32 +105,59 @@ gdb_environ::get (const char *var) const
void
gdb_environ::set (const char *var, const char *value)
{
+ char *fullvar = concat (var, "=", value, NULL);
+
/* We have to unset the variable in the vector if it exists. */
- unset (var);
+ unset (var, false);
/* Insert the element before the last one, which is always NULL. */
- m_environ_vector.insert (m_environ_vector.end () - 1,
- concat (var, "=", value, NULL));
+ m_environ_vector.insert (m_environ_vector.end () - 1, fullvar);
+
+ /* Mark this environment variable as having been set by the user.
+ This will be useful when we deal with setting environment
+ variables on the remote target. */
+ m_user_set_env.insert (std::string (fullvar));
+
+ /* If this environment variable is marked as unset by the user, then
+ remove it from the list, because now the user wants to set
+ it. */
+ m_user_unset_env.erase (std::string (var));
}
/* See common/environ.h. */
void
-gdb_environ::unset (const char *var)
+gdb_environ::unset (const char *var, bool update_unset_list)
{
size_t len = strlen (var);
+ std::vector<char *>::iterator it_env;
/* We iterate until '.end () - 1' because the last element is
always NULL. */
- for (std::vector<char *>::iterator el = m_environ_vector.begin ();
- el != m_environ_vector.end () - 1;
- ++el)
- if (match_var_in_string (*el, var, len))
- {
- xfree (*el);
- m_environ_vector.erase (el);
- break;
- }
+ for (it_env = m_environ_vector.begin ();
+ it_env != m_environ_vector.end () - 1;
+ ++it_env)
+ if (match_var_in_string (*it_env, var, len))
+ break;
+
+ if (it_env != m_environ_vector.end () - 1)
+ {
+ m_user_set_env.erase (std::string (*it_env));
+ xfree (*it_env);
+
+ m_environ_vector.erase (it_env);
+ }
+
+ if (update_unset_list)
+ m_user_unset_env.insert (std::string (var));
+}
+
+/* See common/environ.h. */
+
+void
+gdb_environ::unset (const char *var)
+{
+ unset (var, true);
}
/* See common/environ.h. */
@@ -134,3 +167,17 @@ gdb_environ::envp () const
{
return const_cast<char **> (&m_environ_vector[0]);
}
+
+/* See common/environ.h. */
+
+const std::set<std::string> &
+gdb_environ::user_set_env () const
+{
+ return m_user_set_env;
+}
+
+const std::set<std::string> &
+gdb_environ::user_unset_env () const
+{
+ return m_user_unset_env;
+}
diff --git a/gdb/common/environ.h b/gdb/common/environ.h
index 0bbb191..4003f4e 100644
--- a/gdb/common/environ.h
+++ b/gdb/common/environ.h
@@ -18,6 +18,7 @@
#define ENVIRON_H 1
#include <vector>
+#include <set>
/* Class that represents the environment variables as seen by the
inferior. */
@@ -41,12 +42,16 @@ public:
/* Move constructor. */
gdb_environ (gdb_environ &&e)
- : m_environ_vector (std::move (e.m_environ_vector))
+ : m_environ_vector (std::move (e.m_environ_vector)),
+ m_user_set_env (std::move (e.m_user_set_env)),
+ m_user_unset_env (std::move (e.m_user_unset_env))
{
/* Make sure that the moved-from vector is left at a valid
state (only one NULL element). */
e.m_environ_vector.clear ();
e.m_environ_vector.push_back (NULL);
+ e.m_user_set_env.clear ();
+ e.m_user_unset_env.clear ();
}
/* Move assignment. */
@@ -73,9 +78,26 @@ public:
/* Return the environment vector represented as a 'char **'. */
char **envp () const;
+ /* Return the user-set environment vector. */
+ const std::set<std::string> &user_set_env () const;
+
+ /* Return the user-unset environment vector. */
+ const std::set<std::string> &user_unset_env () const;
+
private:
+ /* Unset VAR in environment. If UPDATE_UNSET_LIST is true, then
+ also update M_USER_UNSET_ENV to reflect the unsetting of the
+ environment variable. */
+ void unset (const char *var, bool update_unset_list);
+
/* A vector containing the environment variables. */
std::vector<char *> m_environ_vector;
+
+ /* The environment variables explicitly set by the user. */
+ std::set<std::string> m_user_set_env;
+
+ /* The environment variables explicitly unset by the user. */
+ std::set<std::string> m_user_unset_env;
};
#endif /* defined (ENVIRON_H) */
diff --git a/gdb/common/rsp-low.c b/gdb/common/rsp-low.c
index eb85ab5..4befeb1 100644
--- a/gdb/common/rsp-low.c
+++ b/gdb/common/rsp-low.c
@@ -132,6 +132,30 @@ hex2bin (const char *hex, gdb_byte *bin, int count)
/* See rsp-low.h. */
+std::string
+hex2str (const char *hex)
+{
+ std::string ret;
+ size_t len = strlen (hex);
+
+ ret.reserve (len / 2);
+ for (size_t i = 0; i < len; ++i)
+ {
+ if (hex[0] == '\0' || hex[1] == '\0')
+ {
+ /* Hex string is short, or of uneven length. Return what we
+ have so far. */
+ return ret;
+ }
+ ret += fromhex (hex[0]) * 16 + fromhex (hex[1]);
+ hex += 2;
+ }
+
+ return ret;
+}
+
+/* See rsp-low.h. */
+
int
bin2hex (const gdb_byte *bin, char *hex, int count)
{
@@ -146,6 +170,23 @@ bin2hex (const gdb_byte *bin, char *hex, int count)
return i;
}
+/* See rsp-low.h. */
+
+std::string
+bin2hex (const gdb_byte *bin, int count)
+{
+ std::string ret;
+
+ ret.reserve (count * 2);
+ for (int i = 0; i < count; ++i)
+ {
+ ret += tohex ((*bin >> 4) & 0xf);
+ ret += tohex (*bin++ & 0xf);
+ }
+
+ return ret;
+}
+
/* Return whether byte B needs escaping when sent as part of binary data. */
static int
diff --git a/gdb/common/rsp-low.h b/gdb/common/rsp-low.h
index b57f58b..2b3685f 100644
--- a/gdb/common/rsp-low.h
+++ b/gdb/common/rsp-low.h
@@ -52,6 +52,10 @@ extern char *unpack_varlen_hex (char *buff, ULONGEST *result);
extern int hex2bin (const char *hex, gdb_byte *bin, int count);
+/* Like hex2bin, but return a std::string. */
+
+extern std::string hex2str (const char *hex);
+
/* Convert some bytes to a hexadecimal representation. BIN holds the
bytes to convert. COUNT says how many bytes to convert. The
resulting characters are stored in HEX, followed by a NUL
@@ -59,6 +63,10 @@ extern int hex2bin (const char *hex, gdb_byte *bin, int count);
extern int bin2hex (const gdb_byte *bin, char *hex, int count);
+/* Overloaded version of bin2hex that returns a std::string. */
+
+extern std::string bin2hex (const gdb_byte *bin, int count);
+
/* Convert BUFFER, binary data at least LEN_UNITS addressable memory units
long, into escaped binary data in OUT_BUF. Only copy memory units that fit
completely in OUT_BUF. Set *OUT_LEN_UNITS to the number of units from