[Lldb-commits] [lldb] 2dec826 - Create basic SBEnvironment class
Walter Erquinigo via lldb-commits
lldb-commits at lists.llvm.org
Fri Mar 20 14:39:36 PDT 2020
Author: Walter Erquinigo
Date: 2020-03-20T14:38:50-07:00
New Revision: 2dec82652e4b6424e46e7bd674cb6404e01e218e
URL: https://github.com/llvm/llvm-project/commit/2dec82652e4b6424e46e7bd674cb6404e01e218e
DIFF: https://github.com/llvm/llvm-project/commit/2dec82652e4b6424e46e7bd674cb6404e01e218e.diff
LOG: Create basic SBEnvironment class
Summary: Inspired by https://reviews.llvm.org/D74636, I'm introducing a basic version of Environment in the API. More functionalities can be added as needed.
Reviewers: labath, clayborg
Subscribers: mgorny, lldb-commits, diazhector98
Tags: #lldb
Differential Revision: https://reviews.llvm.org/D76111
Added:
lldb/bindings/interface/SBEnvironment.i
lldb/include/lldb/API/SBEnvironment.h
lldb/source/API/SBEnvironment.cpp
lldb/test/API/python_api/sbenvironment/TestSBEnvironment.py
Modified:
lldb/bindings/headers.swig
lldb/bindings/interface/SBLaunchInfo.i
lldb/bindings/interface/SBPlatform.i
lldb/bindings/interface/SBTarget.i
lldb/bindings/interfaces.swig
lldb/include/lldb/API/LLDB.h
lldb/include/lldb/API/SBDefines.h
lldb/include/lldb/API/SBLaunchInfo.h
lldb/include/lldb/API/SBPlatform.h
lldb/include/lldb/API/SBTarget.h
lldb/include/lldb/Utility/Environment.h
lldb/include/lldb/lldb-forward.h
lldb/source/API/CMakeLists.txt
lldb/source/API/SBLaunchInfo.cpp
lldb/source/API/SBPlatform.cpp
lldb/source/API/SBTarget.cpp
Removed:
################################################################################
diff --git a/lldb/bindings/headers.swig b/lldb/bindings/headers.swig
index ddd3964beb48..7371e1a3873b 100644
--- a/lldb/bindings/headers.swig
+++ b/lldb/bindings/headers.swig
@@ -21,6 +21,7 @@
#include "lldb/API/SBData.h"
#include "lldb/API/SBDebugger.h"
#include "lldb/API/SBDeclaration.h"
+#include "lldb/API/SBEnvironment.h"
#include "lldb/API/SBError.h"
#include "lldb/API/SBEvent.h"
#include "lldb/API/SBExecutionContext.h"
diff --git a/lldb/bindings/interface/SBEnvironment.i b/lldb/bindings/interface/SBEnvironment.i
new file mode 100644
index 000000000000..4ca22fc314d2
--- /dev/null
+++ b/lldb/bindings/interface/SBEnvironment.i
@@ -0,0 +1,48 @@
+//===-- SWIG Interface for SBEnvironment-------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+namespace lldb {
+
+%feature("docstring",
+"Represents the environment of a certain process.
+
+Example:
+ for entry in lldb.debugger.GetSelectedTarget().GetEnvironment().GetEntries():
+ print(entry)
+
+") SBEnvironment;
+class SBEnvironment {
+public:
+ SBEnvironment ();
+
+ SBEnvironment (const lldb::SBEnvironment &rhs);
+
+ ~SBEnvironment();
+
+ size_t GetNumValues();
+
+ const char *Get(const char *name);
+
+ const char *GetNameAtIndex(size_t index);
+
+ const char *GetValueAtIndex(size_t index);
+
+ SBStringList GetEntries();
+
+ void PutEntry(const char *name_and_value);
+
+ void SetEntries(const SBStringList &entries, bool append);
+
+ bool Set(const char *name, const char *value, bool overwrite);
+
+ bool Unset(const char *name);
+
+ void Clear();
+};
+
+} // namespace lldb
diff --git a/lldb/bindings/interface/SBLaunchInfo.i b/lldb/bindings/interface/SBLaunchInfo.i
index e76950c6fb48..1de89b58b272 100644
--- a/lldb/bindings/interface/SBLaunchInfo.i
+++ b/lldb/bindings/interface/SBLaunchInfo.i
@@ -64,6 +64,12 @@ public:
void
SetEnvironmentEntries (const char **envp, bool append);
+ void
+ SetEnvironment(const SBEnvironment &env, bool append);
+
+ SBEnvironment
+ GetEnvironment();
+
void
Clear ();
diff --git a/lldb/bindings/interface/SBPlatform.i b/lldb/bindings/interface/SBPlatform.i
index 1f52edb0232c..81945222c059 100644
--- a/lldb/bindings/interface/SBPlatform.i
+++ b/lldb/bindings/interface/SBPlatform.i
@@ -194,6 +194,9 @@ public:
lldb::SBUnixSignals
GetUnixSignals();
+ lldb::SBEnvironment
+ GetEnvironment();
+
};
} // namespace lldb
diff --git a/lldb/bindings/interface/SBTarget.i b/lldb/bindings/interface/SBTarget.i
index 371bf5c35ebd..57b5ccea6399 100644
--- a/lldb/bindings/interface/SBTarget.i
+++ b/lldb/bindings/interface/SBTarget.i
@@ -677,6 +677,9 @@ public:
lldb::SBBreakpoint
BreakpointCreateByAddress (addr_t address);
+ lldb::SBEnvironment
+ GetEnvironment();
+
lldb::SBBreakpoint
BreakpointCreateBySBAddress (SBAddress &sb_address);
diff --git a/lldb/bindings/interfaces.swig b/lldb/bindings/interfaces.swig
index 780fe34392ff..e906bb9e5656 100644
--- a/lldb/bindings/interfaces.swig
+++ b/lldb/bindings/interfaces.swig
@@ -29,6 +29,7 @@
%include "./interface/SBDebugger.i"
%include "./interface/SBDeclaration.i"
%include "./interface/SBError.i"
+%include "./interface/SBEnvironment.i"
%include "./interface/SBEvent.i"
%include "./interface/SBExecutionContext.i"
%include "./interface/SBExpressionOptions.i"
diff --git a/lldb/include/lldb/API/LLDB.h b/lldb/include/lldb/API/LLDB.h
index 12f3b8f32f57..83c38d3b6166 100644
--- a/lldb/include/lldb/API/LLDB.h
+++ b/lldb/include/lldb/API/LLDB.h
@@ -24,6 +24,7 @@
#include "lldb/API/SBDebugger.h"
#include "lldb/API/SBDeclaration.h"
#include "lldb/API/SBDefines.h"
+#include "lldb/API/SBEnvironment.h"
#include "lldb/API/SBError.h"
#include "lldb/API/SBEvent.h"
#include "lldb/API/SBExecutionContext.h"
diff --git a/lldb/include/lldb/API/SBDefines.h b/lldb/include/lldb/API/SBDefines.h
index 474692c8c78d..0ddf594e5cb5 100644
--- a/lldb/include/lldb/API/SBDefines.h
+++ b/lldb/include/lldb/API/SBDefines.h
@@ -35,6 +35,7 @@ class LLDB_API SBCompileUnit;
class LLDB_API SBData;
class LLDB_API SBDebugger;
class LLDB_API SBDeclaration;
+class LLDB_API SBEnvironment;
class LLDB_API SBError;
class LLDB_API SBEvent;
class LLDB_API SBEventList;
diff --git a/lldb/include/lldb/API/SBEnvironment.h b/lldb/include/lldb/API/SBEnvironment.h
new file mode 100644
index 000000000000..6e0c5e6fa552
--- /dev/null
+++ b/lldb/include/lldb/API/SBEnvironment.h
@@ -0,0 +1,137 @@
+//===-- SBEnvironment.h -----------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_API_SBENVIRONMENT_H
+#define LLDB_API_SBENVIRONMENT_H
+
+#include "lldb/API/SBDefines.h"
+
+namespace lldb {
+
+class LLDB_API SBEnvironment {
+public:
+ SBEnvironment();
+
+ SBEnvironment(const lldb::SBEnvironment &rhs);
+
+ ~SBEnvironment();
+
+ lldb::SBEnvironment &operator=(const lldb::SBEnvironment &rhs);
+
+ /// Return the value of a given environment variable.
+ ///
+ /// \param [in] name
+ /// The name of the environment variable.
+ ///
+ /// \return
+ /// The value of the enviroment variable or null if not present.
+ /// If the environment variable has no value but is present, a valid
+ /// pointer to an empty string will be returned.
+ const char *Get(const char *name);
+
+ /// \return
+ /// The number of environment variables.
+ size_t GetNumValues();
+
+ /// Return the name of the environment variable at a given index from the
+ /// internal list of environment variables.
+ ///
+ /// \param [in] index
+ /// The index of the environment variable in the internal list.
+ ///
+ /// \return
+ /// The name at the given index or null if the index is invalid.
+ const char *GetNameAtIndex(size_t index);
+
+ /// Return the value of the environment variable at a given index from the
+ /// internal list of environment variables.
+ ///
+ /// \param [in] index
+ /// The index of the environment variable in the internal list.
+ ///
+ /// \return
+ /// The value at the given index or null if the index is invalid.
+ /// If the environment variable has no value but is present, a valid
+ /// pointer to an empty string will be returned.
+ const char *GetValueAtIndex(size_t index);
+
+ /// Return all environment variables contained in this object. Each variable
+ /// is returned as a string with the following format
+ /// name=value
+ ///
+ /// \return
+ /// Return an lldb::SBStringList object with the environment variables.
+ SBStringList GetEntries();
+
+ /// Add or replace an existing environment variable. The input must be a
+ /// string with the format
+ /// name=value
+ ///
+ /// \param [in] name_and_value
+ /// The entry to set which conforms to the format mentioned above.
+ void PutEntry(const char *name_and_value);
+
+ /// Update this object with the given environment variables. The input is a
+ /// list of entries with the same format required by SBEnvironment::PutEntry.
+ ///
+ /// If append is false, the provided environment will replace the existing
+ /// environment. Otherwise, existing values will be updated of left untouched
+ /// accordingly.
+ ///
+ /// \param [in] entries
+ /// The environment variable entries.
+ ///
+ /// \param [in] append
+ /// Flag that controls whether to replace the existing environment.
+ void SetEntries(const SBStringList &entries, bool append);
+
+ /// Set the value of a given environment variable.
+ /// If the variable exists, its value is updated only if overwrite is true.
+ ///
+ /// \param [in] name
+ /// The name of the environment variable to set.
+ ///
+ /// \param [in] value
+ /// The value of the environment variable to set.
+ ///
+ /// \param [in] overwrite
+ /// Flag that indicates whether to overwrite an existing environment
+ /// variable.
+ ///
+ /// \return
+ /// Return whether the variable was added or modified.
+ bool Set(const char *name, const char *value, bool overwrite);
+
+ /// Unset an environment variable if exists.
+ ///
+ /// \param [in] name
+ /// The name of the environment variable to unset.
+ ///
+ /// \return
+ /// Return whether a variable was actually unset.
+ bool Unset(const char *name);
+
+ /// Delete all the environment variables.
+ void Clear();
+
+protected:
+ friend class SBPlatform;
+ friend class SBTarget;
+ friend class SBLaunchInfo;
+
+ SBEnvironment(lldb_private::Environment rhs);
+
+ lldb_private::Environment &ref() const;
+
+private:
+ std::unique_ptr<lldb_private::Environment> m_opaque_up;
+};
+
+} // namespace lldb
+
+#endif // LLDB_API_SBENVIRONMENT_H
diff --git a/lldb/include/lldb/API/SBLaunchInfo.h b/lldb/include/lldb/API/SBLaunchInfo.h
index 883f17c0a57c..04ebb5707688 100644
--- a/lldb/include/lldb/API/SBLaunchInfo.h
+++ b/lldb/include/lldb/API/SBLaunchInfo.h
@@ -94,8 +94,41 @@ class LLDB_API SBLaunchInfo {
const char *GetEnvironmentEntryAtIndex(uint32_t idx);
+ /// Update this object with the given environment variables.
+ ///
+ /// If append is false, the provided environment will replace the existing
+ /// environment. Otherwise, existing values will be updated of left untouched
+ /// accordingly.
+ ///
+ /// \param [in] envp
+ /// The new environment variables as a list of strings with the following
+ /// format
+ /// name=value
+ ///
+ /// \param [in] append
+ /// Flag that controls whether to replace the existing environment.
void SetEnvironmentEntries(const char **envp, bool append);
+ /// Update this object with the given environment variables.
+ ///
+ /// If append is false, the provided environment will replace the existing
+ /// environment. Otherwise, existing values will be updated of left untouched
+ /// accordingly.
+ ///
+ /// \param [in] env
+ /// The new environment variables.
+ ///
+ /// \param [in] append
+ /// Flag that controls whether to replace the existing environment.
+ void SetEnvironment(const SBEnvironment &env, bool append);
+
+ /// Return the environment variables of this object.
+ ///
+ /// \return
+ /// An lldb::SBEnvironment object which is a copy of the SBLaunchInfo's
+ /// environment.
+ SBEnvironment GetEnvironment();
+
void Clear();
const char *GetWorkingDirectory() const;
diff --git a/lldb/include/lldb/API/SBPlatform.h b/lldb/include/lldb/API/SBPlatform.h
index 7fac182a0dd1..34f34de5381e 100644
--- a/lldb/include/lldb/API/SBPlatform.h
+++ b/lldb/include/lldb/API/SBPlatform.h
@@ -154,6 +154,14 @@ class LLDB_API SBPlatform {
SBUnixSignals GetUnixSignals() const;
+ /// Return the environment variables of the remote platform connection
+ /// process.
+ ///
+ /// \return
+ /// An lldb::SBEnvironment object which is a copy of the platform's
+ /// enviroment.
+ SBEnvironment GetEnvironment();
+
protected:
friend class SBDebugger;
friend class SBTarget;
diff --git a/lldb/include/lldb/API/SBTarget.h b/lldb/include/lldb/API/SBTarget.h
index a50e791d4fe3..38ad69427419 100644
--- a/lldb/include/lldb/API/SBTarget.h
+++ b/lldb/include/lldb/API/SBTarget.h
@@ -94,6 +94,15 @@ class LLDB_API SBTarget {
/// A platform object.
lldb::SBPlatform GetPlatform();
+ /// Return the environment variables that would be used to launch a new
+ /// process.
+ ///
+ /// \return
+ /// An lldb::SBEnvironment object which is a copy of the target's
+ /// environment.
+
+ SBEnvironment GetEnvironment();
+
/// Install any binaries that need to be installed.
///
/// This function does nothing when debugging on the host system.
diff --git a/lldb/include/lldb/Utility/Environment.h b/lldb/include/lldb/Utility/Environment.h
index 331eab9f7f0b..e2af2eb2463d 100644
--- a/lldb/include/lldb/Utility/Environment.h
+++ b/lldb/include/lldb/Utility/Environment.h
@@ -50,6 +50,7 @@ class Environment : private llvm::StringMap<std::string> {
using Base::erase;
using Base::find;
using Base::insert;
+ using Base::insert_or_assign;
using Base::lookup;
using Base::size;
using Base::try_emplace;
diff --git a/lldb/include/lldb/lldb-forward.h b/lldb/include/lldb/lldb-forward.h
index 6b22e50a553d..4fd2a07dd616 100644
--- a/lldb/include/lldb/lldb-forward.h
+++ b/lldb/include/lldb/lldb-forward.h
@@ -76,6 +76,7 @@ class DynamicCheckerFunctions;
class DynamicLoader;
class Editline;
class EmulateInstruction;
+class Environment;
class EvaluateExpressionOptions;
class Event;
class EventData;
diff --git a/lldb/source/API/CMakeLists.txt b/lldb/source/API/CMakeLists.txt
index e0ecf29b502b..f8ed1b37f4fa 100644
--- a/lldb/source/API/CMakeLists.txt
+++ b/lldb/source/API/CMakeLists.txt
@@ -35,6 +35,7 @@ add_lldb_library(liblldb SHARED ${option_framework}
SBData.cpp
SBDebugger.cpp
SBDeclaration.cpp
+ SBEnvironment.cpp
SBError.cpp
SBEvent.cpp
SBExecutionContext.cpp
diff --git a/lldb/source/API/SBEnvironment.cpp b/lldb/source/API/SBEnvironment.cpp
new file mode 100644
index 000000000000..8da8184961cd
--- /dev/null
+++ b/lldb/source/API/SBEnvironment.cpp
@@ -0,0 +1,147 @@
+//===-- SBEnvironment.cpp -------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/API/SBEnvironment.h"
+#include "SBReproducerPrivate.h"
+#include "Utils.h"
+#include "lldb/API/SBStringList.h"
+#include "lldb/Utility/Environment.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+SBEnvironment::SBEnvironment() : m_opaque_up(new Environment()) {
+ LLDB_RECORD_CONSTRUCTOR_NO_ARGS(SBEnvironment);
+}
+
+SBEnvironment::SBEnvironment(const SBEnvironment &rhs)
+ : m_opaque_up(clone(rhs.m_opaque_up)) {
+ LLDB_RECORD_CONSTRUCTOR(SBEnvironment, (const lldb::SBEnvironment &), rhs);
+}
+
+SBEnvironment::SBEnvironment(Environment rhs)
+ : m_opaque_up(new Environment(std::move(rhs))) {}
+
+SBEnvironment::~SBEnvironment() = default;
+
+SBEnvironment &SBEnvironment::operator=(const SBEnvironment &rhs) {
+ LLDB_RECORD_METHOD(lldb::SBEnvironment &,
+ SBEnvironment, operator=,(const lldb::SBEnvironment &),
+ rhs);
+
+ if (this != &rhs)
+ m_opaque_up = clone(rhs.m_opaque_up);
+ return LLDB_RECORD_RESULT(*this);
+}
+
+size_t SBEnvironment::GetNumValues() {
+ LLDB_RECORD_METHOD_NO_ARGS(size_t, SBEnvironment, GetNumValues);
+ return LLDB_RECORD_RESULT(m_opaque_up->size());
+}
+
+const char *SBEnvironment::Get(const char *name) {
+ LLDB_RECORD_METHOD(const char *, SBEnvironment, Get, (const char *), name);
+ auto entry = m_opaque_up->find(name);
+ if (entry == m_opaque_up->end())
+ return LLDB_RECORD_RESULT(nullptr);
+ return LLDB_RECORD_RESULT(ConstString(entry->second).AsCString(""));
+}
+
+const char *SBEnvironment::GetNameAtIndex(size_t index) {
+ LLDB_RECORD_METHOD(const char *, SBEnvironment, GetNameAtIndex, (size_t),
+ index);
+ if (index >= GetNumValues())
+ return LLDB_RECORD_RESULT(nullptr);
+ return LLDB_RECORD_RESULT(
+ ConstString(std::next(m_opaque_up->begin(), index)->first())
+ .AsCString(""));
+}
+
+const char *SBEnvironment::GetValueAtIndex(size_t index) {
+ LLDB_RECORD_METHOD(const char *, SBEnvironment, GetValueAtIndex, (size_t),
+ index);
+ if (index < 0 || index >= GetNumValues())
+ return LLDB_RECORD_RESULT(nullptr);
+ return LLDB_RECORD_RESULT(
+ ConstString(std::next(m_opaque_up->begin(), index)->second)
+ .AsCString(""));
+}
+
+bool SBEnvironment::Set(const char *name, const char *value, bool overwrite) {
+ LLDB_RECORD_METHOD(bool, SBEnvironment, Set,
+ (const char *, const char *, bool), name, value,
+ overwrite);
+ if (overwrite) {
+ m_opaque_up->insert_or_assign(name, std::string(value));
+ return LLDB_RECORD_RESULT(true);
+ }
+ return LLDB_RECORD_RESULT(
+ m_opaque_up->try_emplace(name, std::string(value)).second);
+}
+
+bool SBEnvironment::Unset(const char *name) {
+ LLDB_RECORD_METHOD(bool, SBEnvironment, Unset, (const char *), name);
+ return LLDB_RECORD_RESULT(m_opaque_up->erase(name));
+}
+
+SBStringList SBEnvironment::GetEntries() {
+ LLDB_RECORD_METHOD_NO_ARGS(lldb::SBStringList, SBEnvironment, GetEntries);
+ SBStringList entries;
+ for (const auto &KV : *m_opaque_up) {
+ entries.AppendString(Environment::compose(KV).c_str());
+ }
+ return LLDB_RECORD_RESULT(entries);
+}
+
+void SBEnvironment::PutEntry(const char *name_and_value) {
+ LLDB_RECORD_METHOD(void, SBEnvironment, PutEntry, (const char *),
+ name_and_value);
+ auto split = llvm::StringRef(name_and_value).split('=');
+ m_opaque_up->insert_or_assign(split.first.str(), split.second.str());
+}
+
+void SBEnvironment::SetEntries(const SBStringList &entries, bool append) {
+ LLDB_RECORD_METHOD(void, SBEnvironment, SetEntries,
+ (const SBStringList &, bool), entries, append);
+ if (!append)
+ m_opaque_up->clear();
+ for (size_t i = 0; i < entries.GetSize(); i++) {
+ PutEntry(entries.GetStringAtIndex(i));
+ }
+}
+
+void SBEnvironment::Clear() {
+ LLDB_RECORD_METHOD_NO_ARGS(void, SBEnvironment, Clear);
+ m_opaque_up->clear();
+}
+
+Environment &SBEnvironment::ref() const { return *m_opaque_up; }
+
+namespace lldb_private {
+namespace repro {
+
+template <> void RegisterMethods<SBEnvironment>(Registry &R) {
+ LLDB_REGISTER_CONSTRUCTOR(SBEnvironment, ());
+ LLDB_REGISTER_CONSTRUCTOR(SBEnvironment, (const lldb::SBEnvironment &));
+ LLDB_REGISTER_METHOD(lldb::SBEnvironment &,
+ SBEnvironment, operator=,(const lldb::SBEnvironment &));
+ LLDB_REGISTER_METHOD(size_t, SBEnvironment, GetNumValues, ());
+ LLDB_REGISTER_METHOD(const char *, SBEnvironment, GetNameAtIndex, (size_t));
+ LLDB_REGISTER_METHOD(const char *, SBEnvironment, GetValueAtIndex, (size_t));
+ LLDB_REGISTER_METHOD(const char *, SBEnvironment, Get, (const char *));
+ LLDB_REGISTER_METHOD(bool, SBEnvironment, Set,
+ (const char *, const char *, bool));
+ LLDB_REGISTER_METHOD(bool, SBEnvironment, Unset, (const char *));
+ LLDB_REGISTER_METHOD(lldb::SBStringList, SBEnvironment, GetEntries, ());
+ LLDB_REGISTER_METHOD(void, SBEnvironment, PutEntry, (const char *));
+ LLDB_REGISTER_METHOD(void, SBEnvironment, SetEntries,
+ (const SBStringList &, bool));
+}
+
+} // namespace repro
+} // namespace lldb_private
diff --git a/lldb/source/API/SBLaunchInfo.cpp b/lldb/source/API/SBLaunchInfo.cpp
index 58307077153d..ba13072e8f9b 100644
--- a/lldb/source/API/SBLaunchInfo.cpp
+++ b/lldb/source/API/SBLaunchInfo.cpp
@@ -9,6 +9,7 @@
#include "lldb/API/SBLaunchInfo.h"
#include "SBReproducerPrivate.h"
+#include "lldb/API/SBEnvironment.h"
#include "lldb/API/SBFileSpec.h"
#include "lldb/API/SBListener.h"
#include "lldb/Host/ProcessLaunchInfo.h"
@@ -182,15 +183,26 @@ const char *SBLaunchInfo::GetEnvironmentEntryAtIndex(uint32_t idx) {
void SBLaunchInfo::SetEnvironmentEntries(const char **envp, bool append) {
LLDB_RECORD_METHOD(void, SBLaunchInfo, SetEnvironmentEntries,
(const char **, bool), envp, append);
+ SetEnvironment(SBEnvironment(Environment(envp)), append);
+}
- Environment env(envp);
+void SBLaunchInfo::SetEnvironment(const SBEnvironment &env, bool append) {
+ LLDB_RECORD_METHOD(void, SBLaunchInfo, SetEnvironment,
+ (const lldb::SBEnvironment &, bool), env, append);
+ Environment &refEnv = env.ref();
if (append)
- m_opaque_sp->GetEnvironment().insert(env.begin(), env.end());
+ m_opaque_sp->GetEnvironment().insert(refEnv.begin(), refEnv.end());
else
- m_opaque_sp->GetEnvironment() = env;
+ m_opaque_sp->GetEnvironment() = refEnv;
m_opaque_sp->RegenerateEnvp();
}
+SBEnvironment SBLaunchInfo::GetEnvironment() {
+ LLDB_RECORD_METHOD_NO_ARGS(lldb::SBEnvironment, SBLaunchInfo, GetEnvironment);
+ return LLDB_RECORD_RESULT(
+ SBEnvironment(Environment(m_opaque_sp->GetEnvironment())));
+}
+
void SBLaunchInfo::Clear() {
LLDB_RECORD_METHOD_NO_ARGS(void, SBLaunchInfo, Clear);
@@ -390,6 +402,9 @@ void RegisterMethods<SBLaunchInfo>(Registry &R) {
());
LLDB_REGISTER_METHOD(void, SBLaunchInfo, SetDetachOnError, (bool));
LLDB_REGISTER_METHOD_CONST(bool, SBLaunchInfo, GetDetachOnError, ());
+ LLDB_REGISTER_METHOD(void, SBLaunchInfo, SetEnvironment,
+ (const lldb::SBEnvironment &, bool));
+ LLDB_REGISTER_METHOD(lldb::SBEnvironment, SBLaunchInfo, GetEnvironment, ());
}
}
diff --git a/lldb/source/API/SBPlatform.cpp b/lldb/source/API/SBPlatform.cpp
index 7aa0b54d0005..ddb77f4f008a 100644
--- a/lldb/source/API/SBPlatform.cpp
+++ b/lldb/source/API/SBPlatform.cpp
@@ -8,9 +8,11 @@
#include "lldb/API/SBPlatform.h"
#include "SBReproducerPrivate.h"
+#include "lldb/API/SBEnvironment.h"
#include "lldb/API/SBError.h"
#include "lldb/API/SBFileSpec.h"
#include "lldb/API/SBLaunchInfo.h"
+#include "lldb/API/SBPlatform.h"
#include "lldb/API/SBUnixSignals.h"
#include "lldb/Host/File.h"
#include "lldb/Target/Platform.h"
@@ -649,6 +651,17 @@ SBUnixSignals SBPlatform::GetUnixSignals() const {
return LLDB_RECORD_RESULT(SBUnixSignals());
}
+SBEnvironment SBPlatform::GetEnvironment() {
+ LLDB_RECORD_METHOD_NO_ARGS(lldb::SBEnvironment, SBPlatform, GetEnvironment);
+ PlatformSP platform_sp(GetSP());
+
+ if (platform_sp) {
+ return LLDB_RECORD_RESULT(SBEnvironment(platform_sp->GetEnvironment()));
+ }
+
+ return LLDB_RECORD_RESULT(SBEnvironment());
+}
+
namespace lldb_private {
namespace repro {
@@ -740,6 +753,7 @@ void RegisterMethods<SBPlatform>(Registry &R) {
(const char *));
LLDB_REGISTER_METHOD(lldb::SBError, SBPlatform, SetFilePermissions,
(const char *, uint32_t));
+ LLDB_REGISTER_METHOD(lldb::SBEnvironment, SBPlatform, GetEnvironment, ());
LLDB_REGISTER_METHOD_CONST(lldb::SBUnixSignals, SBPlatform, GetUnixSignals,
());
}
diff --git a/lldb/source/API/SBTarget.cpp b/lldb/source/API/SBTarget.cpp
index b90e77280d24..d33c688652a9 100644
--- a/lldb/source/API/SBTarget.cpp
+++ b/lldb/source/API/SBTarget.cpp
@@ -13,6 +13,7 @@
#include "lldb/API/SBBreakpoint.h"
#include "lldb/API/SBDebugger.h"
+#include "lldb/API/SBEnvironment.h"
#include "lldb/API/SBEvent.h"
#include "lldb/API/SBExpressionOptions.h"
#include "lldb/API/SBFileSpec.h"
@@ -2388,6 +2389,17 @@ void SBTarget::SetLaunchInfo(const lldb::SBLaunchInfo &launch_info) {
m_opaque_sp->SetProcessLaunchInfo(launch_info.ref());
}
+SBEnvironment SBTarget::GetEnvironment() {
+ LLDB_RECORD_METHOD_NO_ARGS(lldb::SBEnvironment, SBTarget, GetEnvironment);
+ TargetSP target_sp(GetSP());
+
+ if (target_sp) {
+ return LLDB_RECORD_RESULT(SBEnvironment(target_sp->GetEnvironment()));
+ }
+
+ return LLDB_RECORD_RESULT(SBEnvironment());
+}
+
namespace lldb_private {
namespace repro {
@@ -2643,6 +2655,7 @@ void RegisterMethods<SBTarget>(Registry &R) {
LLDB_REGISTER_METHOD(lldb::SBInstructionList, SBTarget,
GetInstructionsWithFlavor,
(lldb::addr_t, const char *, const void *, size_t));
+ LLDB_REGISTER_METHOD(lldb::SBEnvironment, SBTarget, GetEnvironment, ());
}
}
diff --git a/lldb/test/API/python_api/sbenvironment/TestSBEnvironment.py b/lldb/test/API/python_api/sbenvironment/TestSBEnvironment.py
new file mode 100644
index 000000000000..546b908383e7
--- /dev/null
+++ b/lldb/test/API/python_api/sbenvironment/TestSBEnvironment.py
@@ -0,0 +1,125 @@
+"""Test the SBEnvironment APIs."""
+
+
+
+from math import fabs
+import lldb
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+
+class SBEnvironmentAPICase(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+ NO_DEBUG_INFO_TESTCASE = True
+
+ # We use this function to test both kind of accessors:
+ # . Get*AtIndex and GetEntries
+ def assertEqualEntries(self, env, entries):
+ self.assertEqual(env.GetNumValues(), len(entries))
+ for i in range(env.GetNumValues()):
+ name = env.GetNameAtIndex(i)
+ value = env.GetValueAtIndex(i)
+ self.assertIn(name + "=" + value, entries)
+
+ entries = env.GetEntries()
+ self.assertEqual(entries.GetSize(), len(entries))
+ for i in range(entries.GetSize()):
+ (name, value) = entries.GetStringAtIndex(i).split("=")
+ self.assertIn(name + "=" + value, entries)
+
+
+
+ @add_test_categories(['pyapi'])
+ def test_platform_environment(self):
+ env = self.dbg.GetSelectedPlatform().GetEnvironment()
+ # We assume at least PATH is set
+ self.assertNotEqual(env.Get("PATH"), None)
+
+
+ @add_test_categories(['pyapi'])
+ def test_launch_info(self):
+ target = self.dbg.CreateTarget("")
+ launch_info = target.GetLaunchInfo()
+ env = launch_info.GetEnvironment()
+ self.assertEqual(env.GetNumValues(), 0)
+
+ env.Set("FOO", "bar", overwrite=True)
+ self.assertEqual(env.GetNumValues(), 1)
+
+ # Make sure we only modify the copy of the launchInfo's environment
+ self.assertEqual(launch_info.GetEnvironment().GetNumValues(), 0)
+
+ launch_info.SetEnvironment(env, append=True)
+ self.assertEqual(launch_info.GetEnvironment().GetNumValues(), 1)
+
+ # Make sure we can replace the launchInfo's environment
+ env.Clear()
+ env.Set("BAR", "foo", overwrite=True)
+ env.PutEntry("X=y")
+ launch_info.SetEnvironment(env, append=False)
+ self.assertEqualEntries(launch_info.GetEnvironment(), ["BAR=foo", "X=y"])
+
+
+ @add_test_categories(['pyapi'])
+ def test_target_environment(self):
+ env = self.dbg.GetSelectedTarget().GetEnvironment()
+ # There is no target, so env should be empty
+ self.assertEqual(env.GetNumValues(), 0)
+ self.assertEqual(env.Get("PATH"), None)
+
+ target = self.dbg.CreateTarget("")
+ env = target.GetEnvironment()
+ path = env.Get("PATH")
+ # Now there's a target, so at least PATH should exist
+ self.assertNotEqual(path, None)
+
+ # Make sure we are getting a copy by modifying the env we just got
+ env.PutEntry("PATH=#" + path)
+ self.assertEqual(target.GetEnvironment().Get("PATH"), path)
+
+ @add_test_categories(['pyapi'])
+ def test_creating_and_modifying_environment(self):
+ env = lldb.SBEnvironment()
+
+ self.assertEqual(env.Get("FOO"), None)
+ self.assertEqual(env.Get("BAR"), None)
+
+ # We also test empty values
+ self.assertTrue(env.Set("FOO", "", overwrite=False))
+ env.Set("BAR", "foo", overwrite=False)
+
+ self.assertEqual(env.Get("FOO"), "")
+ self.assertEqual(env.Get("BAR"), "foo")
+
+ self.assertEqual(env.GetNumValues(), 2)
+
+ self.assertEqualEntries(env, ["FOO=", "BAR=foo"])
+
+ # Make sure modifications work
+ self.assertFalse(env.Set("FOO", "bar", overwrite=False))
+ self.assertEqual(env.Get("FOO"), "")
+
+ env.PutEntry("FOO=bar")
+ self.assertEqual(env.Get("FOO"), "bar")
+
+ self.assertEqualEntries(env, ["FOO=bar", "BAR=foo"])
+
+ # Make sure we can unset
+ self.assertTrue(env.Unset("FOO"))
+ self.assertFalse(env.Unset("FOO"))
+ self.assertEqual(env.Get("FOO"), None)
+
+ # Test SetEntries
+ entries = lldb.SBStringList()
+ entries.AppendList(["X=x", "Y=y"], 2)
+
+ env.SetEntries(entries, append=True)
+ self.assertEqualEntries(env, ["BAR=foo", "X=x", "Y=y"])
+
+ env.SetEntries(entries, append=False)
+ self.assertEqualEntries(env, ["X=x", "Y=y"])
+
+ # Test clear
+ env.Clear()
+ self.assertEqualEntries(env, [])
More information about the lldb-commits
mailing list