[Lldb-commits] [lldb] Make env and source map dictionaries #95137 (PR #106919)
via lldb-commits
lldb-commits at lists.llvm.org
Mon Sep 2 15:57:09 PDT 2024
https://github.com/Da-Viper updated https://github.com/llvm/llvm-project/pull/106919
>From d2bddca1753b4c960895f51d7eb80b6efa7dc986 Mon Sep 17 00:00:00 2001
From: Ezike Ebuka <yerimyah1 at gmail.com>
Date: Sun, 1 Sep 2024 17:26:11 +0100
Subject: [PATCH 1/3] [lldb-dap] Make environment option an object
---
.../tools/lldb-dap/launch/TestDAP_launch.py | 4 +-
lldb/tools/lldb-dap/JSONUtils.cpp | 40 ++++++++++++++++---
lldb/tools/lldb-dap/JSONUtils.h | 22 ++++++++++
lldb/tools/lldb-dap/README.md | 5 ++-
lldb/tools/lldb-dap/lldb-dap.cpp | 8 +++-
lldb/tools/lldb-dap/package.json | 11 +++--
6 files changed, 77 insertions(+), 13 deletions(-)
diff --git a/lldb/test/API/tools/lldb-dap/launch/TestDAP_launch.py b/lldb/test/API/tools/lldb-dap/launch/TestDAP_launch.py
index a16f2da3c4df71..6b9993a2548b8d 100644
--- a/lldb/test/API/tools/lldb-dap/launch/TestDAP_launch.py
+++ b/lldb/test/API/tools/lldb-dap/launch/TestDAP_launch.py
@@ -229,7 +229,7 @@ def test_environment(self):
Tests launch of a simple program with environment variables
"""
program = self.getBuildArtifact("a.out")
- env = ["NO_VALUE", "WITH_VALUE=BAR", "EMPTY_VALUE=", "SPACE=Hello World"]
+ env = {"NO_VALUE": "", "WITH_VALUE":"BAR", "EMPTY_VALUE": "", "SPACE": "Hello World"}
self.build_and_launch(program, env=env)
self.continue_to_exit()
@@ -242,7 +242,7 @@ def test_environment(self):
lines.pop(0)
# Make sure each environment variable in "env" is actually set in the
# program environment that was printed to STDOUT
- for var in env:
+ for var in env.keys():
found = False
for program_var in lines:
if var in program_var:
diff --git a/lldb/tools/lldb-dap/JSONUtils.cpp b/lldb/tools/lldb-dap/JSONUtils.cpp
index 7338e7cf41eb03..29b3ad490af0b6 100644
--- a/lldb/tools/lldb-dap/JSONUtils.cpp
+++ b/lldb/tools/lldb-dap/JSONUtils.cpp
@@ -136,6 +136,31 @@ std::vector<std::string> GetStrings(const llvm::json::Object *obj,
return strs;
}
+std::unordered_map<std::string, std::string>
+GetStringMap(const llvm::json::Object &obj, llvm::StringRef key) {
+ std::unordered_map<std::string, std::string> strs;
+ const auto *const json_object = obj.getObject(key);
+ if (!json_object)
+ return strs;
+
+ for (const auto &[key, value] : *json_object) {
+ switch (value.kind()) {
+ case llvm::json::Value::String:
+ strs.emplace(key.str(), value.getAsString()->str());
+ break;
+ case llvm::json::Value::Number:
+ case llvm::json::Value::Boolean:
+ strs.emplace(key.str(), llvm::to_string(value));
+ break;
+ case llvm::json::Value::Null:
+ case llvm::json::Value::Object:
+ case llvm::json::Value::Array:
+ break;
+ }
+ }
+ return strs;
+}
+
static bool IsClassStructOrUnionType(lldb::SBType t) {
return (t.GetTypeClass() & (lldb::eTypeClassUnion | lldb::eTypeClassStruct |
lldb::eTypeClassArray)) != 0;
@@ -1370,13 +1395,16 @@ CreateRunInTerminalReverseRequest(const llvm::json::Object &launch_request,
if (!cwd.empty())
run_in_terminal_args.try_emplace("cwd", cwd);
- // We need to convert the input list of environments variables into a
- // dictionary
- std::vector<std::string> envs = GetStrings(launch_request_arguments, "env");
+ std::unordered_map<std::string, std::string> envMap =
+ GetStringMap(*launch_request_arguments, "env");
llvm::json::Object environment;
- for (const std::string &env : envs) {
- size_t index = env.find('=');
- environment.try_emplace(env.substr(0, index), env.substr(index + 1));
+ for (const auto &[key, value] : envMap) {
+ if (key.empty())
+ g_dap.SendOutput(OutputType::Stderr,
+ "empty environment variable for value: \"" + value +
+ '\"');
+ else
+ environment.try_emplace(key, value);
}
run_in_terminal_args.try_emplace("env",
llvm::json::Value(std::move(environment)));
diff --git a/lldb/tools/lldb-dap/JSONUtils.h b/lldb/tools/lldb-dap/JSONUtils.h
index b6356630b72682..60d5db06560657 100644
--- a/lldb/tools/lldb-dap/JSONUtils.h
+++ b/lldb/tools/lldb-dap/JSONUtils.h
@@ -16,6 +16,7 @@
#include "llvm/Support/JSON.h"
#include <cstdint>
#include <optional>
+#include <unordered_map>
namespace lldb_dap {
@@ -152,6 +153,27 @@ bool ObjectContainsKey(const llvm::json::Object &obj, llvm::StringRef key);
std::vector<std::string> GetStrings(const llvm::json::Object *obj,
llvm::StringRef key);
+/// Extract an object of key value strings for the specified key from an object.
+///
+/// String values in the object will be extracted without any quotes
+/// around them. Numbers and Booleans will be converted into
+/// strings. Any NULL, array or objects values in the array will be
+/// ignored.
+///
+/// \param[in] obj
+/// A JSON object that we will attempt to extract the array from
+///
+/// \param[in] key
+/// The key to use when extracting the value
+///
+/// \return
+/// An object of key value strings for the specified \a key, or
+/// \a fail_value if there is no key that matches or if the
+/// value is not an object or key and values in the object are not
+/// strings, numbers or booleans.
+std::unordered_map<std::string, std::string>
+GetStringMap(const llvm::json::Object &obj, llvm::StringRef key);
+
/// Fill a response object given the request object.
///
/// The \a response object will get its "type" set to "response",
diff --git a/lldb/tools/lldb-dap/README.md b/lldb/tools/lldb-dap/README.md
index 11a14d29ab51e2..5b6fc5ef990e60 100644
--- a/lldb/tools/lldb-dap/README.md
+++ b/lldb/tools/lldb-dap/README.md
@@ -77,7 +77,10 @@ adds `FOO=1` and `bar` to the environment:
"name": "Debug",
"program": "/tmp/a.out",
"args": [ "one", "two", "three" ],
- "env": [ "FOO=1", "BAR" ],
+ "env": {
+ "FOO": "1"
+ "BAR": ""
+ }
}
```
diff --git a/lldb/tools/lldb-dap/lldb-dap.cpp b/lldb/tools/lldb-dap/lldb-dap.cpp
index c5c4b09f15622b..da0935dff69878 100644
--- a/lldb/tools/lldb-dap/lldb-dap.cpp
+++ b/lldb/tools/lldb-dap/lldb-dap.cpp
@@ -1831,7 +1831,13 @@ lldb::SBError LaunchProcess(const llvm::json::Object &request) {
launch_info.SetArguments(MakeArgv(args).data(), true);
// Pass any environment variables along that the user specified.
- auto envs = GetStrings(arguments, "env");
+ auto envMap = GetStringMap(*arguments, "env");
+ std::vector<std::string> envs;
+ envs.reserve(envMap.size());
+ for (const auto &[key, value] : envMap) {
+ envs.emplace_back(key + '=' + value);
+ }
+
if (!envs.empty())
launch_info.SetEnvironmentEntries(MakeArgv(envs).data(), true);
diff --git a/lldb/tools/lldb-dap/package.json b/lldb/tools/lldb-dap/package.json
index 4f4261d1718c01..3867302a841913 100644
--- a/lldb/tools/lldb-dap/package.json
+++ b/lldb/tools/lldb-dap/package.json
@@ -160,9 +160,14 @@
"default": "${workspaceRoot}"
},
"env": {
- "type": "array",
- "description": "Additional environment variables to set when launching the program. This is an array of strings that contains the variable name followed by an optional '=' character and the environment variable's value.",
- "default": []
+ "type": "object",
+ "description": "Additional environment variables to set when launching the program. E.g. `{ \"FOO\": \"1\" }`",
+ "patternProperties": {
+ ".*": {
+ "type": "string"
+ }
+ },
+ "default": {}
},
"stopOnEntry": {
"type": "boolean",
>From a3827ed57f655ab803fa28ea7f97e5274322bf0e Mon Sep 17 00:00:00 2001
From: Ezike Ebuka <yerimyah1 at gmail.com>
Date: Mon, 2 Sep 2024 14:25:07 +0100
Subject: [PATCH 2/3] [lldb-dap] format python test code
---
lldb/test/API/tools/lldb-dap/launch/TestDAP_launch.py | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/lldb/test/API/tools/lldb-dap/launch/TestDAP_launch.py b/lldb/test/API/tools/lldb-dap/launch/TestDAP_launch.py
index 6b9993a2548b8d..a56ad032772cbb 100644
--- a/lldb/test/API/tools/lldb-dap/launch/TestDAP_launch.py
+++ b/lldb/test/API/tools/lldb-dap/launch/TestDAP_launch.py
@@ -229,7 +229,12 @@ def test_environment(self):
Tests launch of a simple program with environment variables
"""
program = self.getBuildArtifact("a.out")
- env = {"NO_VALUE": "", "WITH_VALUE":"BAR", "EMPTY_VALUE": "", "SPACE": "Hello World"}
+ env = {
+ "NO_VALUE": "",
+ "WITH_VALUE": "BAR",
+ "EMPTY_VALUE": "",
+ "SPACE": "Hello World",
+ }
self.build_and_launch(program, env=env)
self.continue_to_exit()
>From b0dcf84e0b38dd69813f3aa0f827fb5a70d369f8 Mon Sep 17 00:00:00 2001
From: Ezike Ebuka <yerimyah1 at gmail.com>
Date: Mon, 2 Sep 2024 23:56:40 +0100
Subject: [PATCH 3/3] [lldb-dap] Clean: use Environment class instead of manual
concatenation
---
lldb/tools/lldb-dap/lldb-dap.cpp | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/lldb/tools/lldb-dap/lldb-dap.cpp b/lldb/tools/lldb-dap/lldb-dap.cpp
index da0935dff69878..7df84bd72794fd 100644
--- a/lldb/tools/lldb-dap/lldb-dap.cpp
+++ b/lldb/tools/lldb-dap/lldb-dap.cpp
@@ -51,6 +51,7 @@
#include <thread>
#include <vector>
+#include "lldb/API/SBEnvironment.h"
#include "lldb/API/SBStream.h"
#include "lldb/Host/Config.h"
#include "llvm/ADT/ArrayRef.h"
@@ -1832,14 +1833,13 @@ lldb::SBError LaunchProcess(const llvm::json::Object &request) {
// Pass any environment variables along that the user specified.
auto envMap = GetStringMap(*arguments, "env");
- std::vector<std::string> envs;
- envs.reserve(envMap.size());
+ lldb::SBEnvironment envs{};
for (const auto &[key, value] : envMap) {
- envs.emplace_back(key + '=' + value);
+ envs.Set(key.c_str(), value.c_str(), true);
}
- if (!envs.empty())
- launch_info.SetEnvironmentEntries(MakeArgv(envs).data(), true);
+ if (envs.GetNumValues() != 0)
+ launch_info.SetEnvironment(envs, true);
auto flags = launch_info.GetLaunchFlags();
More information about the lldb-commits
mailing list