diff options
Diffstat (limited to 'gdb/common')
-rw-r--r-- | gdb/common/environ.c | 75 | ||||
-rw-r--r-- | gdb/common/environ.h | 24 | ||||
-rw-r--r-- | gdb/common/rsp-low.c | 41 | ||||
-rw-r--r-- | gdb/common/rsp-low.h | 8 |
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 |