Skip to content

Commit d2bddca

Browse files
committed
[lldb-dap] Make environment option an object
1 parent 87d9048 commit d2bddca

File tree

6 files changed

+77
-13
lines changed

6 files changed

+77
-13
lines changed

lldb/test/API/tools/lldb-dap/launch/TestDAP_launch.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -229,7 +229,7 @@ def test_environment(self):
229229
Tests launch of a simple program with environment variables
230230
"""
231231
program = self.getBuildArtifact("a.out")
232-
env = ["NO_VALUE", "WITH_VALUE=BAR", "EMPTY_VALUE=", "SPACE=Hello World"]
232+
env = {"NO_VALUE": "", "WITH_VALUE":"BAR", "EMPTY_VALUE": "", "SPACE": "Hello World"}
233233
self.build_and_launch(program, env=env)
234234
self.continue_to_exit()
235235

@@ -242,7 +242,7 @@ def test_environment(self):
242242
lines.pop(0)
243243
# Make sure each environment variable in "env" is actually set in the
244244
# program environment that was printed to STDOUT
245-
for var in env:
245+
for var in env.keys():
246246
found = False
247247
for program_var in lines:
248248
if var in program_var:

lldb/tools/lldb-dap/JSONUtils.cpp

Lines changed: 34 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,31 @@ std::vector<std::string> GetStrings(const llvm::json::Object *obj,
136136
return strs;
137137
}
138138

139+
std::unordered_map<std::string, std::string>
140+
GetStringMap(const llvm::json::Object &obj, llvm::StringRef key) {
141+
std::unordered_map<std::string, std::string> strs;
142+
const auto *const json_object = obj.getObject(key);
143+
if (!json_object)
144+
return strs;
145+
146+
for (const auto &[key, value] : *json_object) {
147+
switch (value.kind()) {
148+
case llvm::json::Value::String:
149+
strs.emplace(key.str(), value.getAsString()->str());
150+
break;
151+
case llvm::json::Value::Number:
152+
case llvm::json::Value::Boolean:
153+
strs.emplace(key.str(), llvm::to_string(value));
154+
break;
155+
case llvm::json::Value::Null:
156+
case llvm::json::Value::Object:
157+
case llvm::json::Value::Array:
158+
break;
159+
}
160+
}
161+
return strs;
162+
}
163+
139164
static bool IsClassStructOrUnionType(lldb::SBType t) {
140165
return (t.GetTypeClass() & (lldb::eTypeClassUnion | lldb::eTypeClassStruct |
141166
lldb::eTypeClassArray)) != 0;
@@ -1370,13 +1395,16 @@ CreateRunInTerminalReverseRequest(const llvm::json::Object &launch_request,
13701395
if (!cwd.empty())
13711396
run_in_terminal_args.try_emplace("cwd", cwd);
13721397

1373-
// We need to convert the input list of environments variables into a
1374-
// dictionary
1375-
std::vector<std::string> envs = GetStrings(launch_request_arguments, "env");
1398+
std::unordered_map<std::string, std::string> envMap =
1399+
GetStringMap(*launch_request_arguments, "env");
13761400
llvm::json::Object environment;
1377-
for (const std::string &env : envs) {
1378-
size_t index = env.find('=');
1379-
environment.try_emplace(env.substr(0, index), env.substr(index + 1));
1401+
for (const auto &[key, value] : envMap) {
1402+
if (key.empty())
1403+
g_dap.SendOutput(OutputType::Stderr,
1404+
"empty environment variable for value: \"" + value +
1405+
'\"');
1406+
else
1407+
environment.try_emplace(key, value);
13801408
}
13811409
run_in_terminal_args.try_emplace("env",
13821410
llvm::json::Value(std::move(environment)));

lldb/tools/lldb-dap/JSONUtils.h

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include "llvm/Support/JSON.h"
1717
#include <cstdint>
1818
#include <optional>
19+
#include <unordered_map>
1920

2021
namespace lldb_dap {
2122

@@ -152,6 +153,27 @@ bool ObjectContainsKey(const llvm::json::Object &obj, llvm::StringRef key);
152153
std::vector<std::string> GetStrings(const llvm::json::Object *obj,
153154
llvm::StringRef key);
154155

156+
/// Extract an object of key value strings for the specified key from an object.
157+
///
158+
/// String values in the object will be extracted without any quotes
159+
/// around them. Numbers and Booleans will be converted into
160+
/// strings. Any NULL, array or objects values in the array will be
161+
/// ignored.
162+
///
163+
/// \param[in] obj
164+
/// A JSON object that we will attempt to extract the array from
165+
///
166+
/// \param[in] key
167+
/// The key to use when extracting the value
168+
///
169+
/// \return
170+
/// An object of key value strings for the specified \a key, or
171+
/// \a fail_value if there is no key that matches or if the
172+
/// value is not an object or key and values in the object are not
173+
/// strings, numbers or booleans.
174+
std::unordered_map<std::string, std::string>
175+
GetStringMap(const llvm::json::Object &obj, llvm::StringRef key);
176+
155177
/// Fill a response object given the request object.
156178
///
157179
/// The \a response object will get its "type" set to "response",

lldb/tools/lldb-dap/README.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,10 @@ adds `FOO=1` and `bar` to the environment:
7777
"name": "Debug",
7878
"program": "/tmp/a.out",
7979
"args": [ "one", "two", "three" ],
80-
"env": [ "FOO=1", "BAR" ],
80+
"env": {
81+
"FOO": "1"
82+
"BAR": ""
83+
}
8184
}
8285
```
8386

lldb/tools/lldb-dap/lldb-dap.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1831,7 +1831,13 @@ lldb::SBError LaunchProcess(const llvm::json::Object &request) {
18311831
launch_info.SetArguments(MakeArgv(args).data(), true);
18321832

18331833
// Pass any environment variables along that the user specified.
1834-
auto envs = GetStrings(arguments, "env");
1834+
auto envMap = GetStringMap(*arguments, "env");
1835+
std::vector<std::string> envs;
1836+
envs.reserve(envMap.size());
1837+
for (const auto &[key, value] : envMap) {
1838+
envs.emplace_back(key + '=' + value);
1839+
}
1840+
18351841
if (!envs.empty())
18361842
launch_info.SetEnvironmentEntries(MakeArgv(envs).data(), true);
18371843

lldb/tools/lldb-dap/package.json

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -160,9 +160,14 @@
160160
"default": "${workspaceRoot}"
161161
},
162162
"env": {
163-
"type": "array",
164-
"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.",
165-
"default": []
163+
"type": "object",
164+
"description": "Additional environment variables to set when launching the program. E.g. `{ \"FOO\": \"1\" }`",
165+
"patternProperties": {
166+
".*": {
167+
"type": "string"
168+
}
169+
},
170+
"default": {}
166171
},
167172
"stopOnEntry": {
168173
"type": "boolean",

0 commit comments

Comments
 (0)