Skip to content

Commit 8d6dfcd

Browse files
author
git apple-llvm automerger
committed
Merge commit '2ad0b5c3963d' from apple/stable/20200714 into swift/main
2 parents e471fa4 + 2ad0b5c commit 8d6dfcd

File tree

1 file changed

+42
-2
lines changed

1 file changed

+42
-2
lines changed

lldb/source/Expression/REPL.cpp

Lines changed: 42 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -123,10 +123,11 @@ const char *REPL::IOHandlerGetHelpPrologue() {
123123
"Valid statements, expressions, and declarations are immediately "
124124
"compiled and executed.\n\n"
125125
"The complete set of LLDB debugging commands are also available as "
126-
"described below. Commands "
126+
"described below.\n\nCommands "
127127
"must be prefixed with a colon at the REPL prompt (:quit for "
128128
"example.) Typing just a colon "
129-
"followed by return will switch to the LLDB prompt.\n\n";
129+
"followed by return will switch to the LLDB prompt.\n\n"
130+
"Type “< path” to read in code from a text file “path”.\n\n";
130131
}
131132

132133
bool REPL::IOHandlerIsInputComplete(IOHandler &io_handler, StringList &lines) {
@@ -179,6 +180,36 @@ int REPL::IOHandlerFixIndentation(IOHandler &io_handler,
179180
return (int)desired_indent - actual_indent;
180181
}
181182

183+
static bool ReadCode(const std::string &path, std::string &code,
184+
lldb::StreamFileSP &error_sp) {
185+
auto &fs = FileSystem::Instance();
186+
llvm::Twine pathTwine(path);
187+
if (!fs.Exists(pathTwine)) {
188+
error_sp->Printf("no such file at path '%s'\n", path.c_str());
189+
return false;
190+
}
191+
if (!fs.Readable(pathTwine)) {
192+
error_sp->Printf("could not read file at path '%s'\n", path.c_str());
193+
return false;
194+
}
195+
const size_t file_size = fs.GetByteSize(pathTwine);
196+
const size_t max_size = code.max_size();
197+
if (file_size > max_size) {
198+
error_sp->Printf("file at path '%s' too large: "
199+
"file_size = %llu, max_size = %llu\n",
200+
path.c_str(), file_size, max_size);
201+
return false;
202+
}
203+
auto data_sp = fs.CreateDataBuffer(pathTwine);
204+
if (data_sp == nullptr) {
205+
error_sp->Printf("could not create buffer for file at path '%s'\n",
206+
path.c_str());
207+
return false;
208+
}
209+
code.assign((const char *)data_sp->GetBytes(), data_sp->GetByteSize());
210+
return true;
211+
}
212+
182213
void REPL::IOHandlerInputComplete(IOHandler &io_handler, std::string &code) {
183214
lldb::StreamFileSP output_sp(io_handler.GetOutputStreamFileSP());
184215
lldb::StreamFileSP error_sp(io_handler.GetErrorStreamFileSP());
@@ -257,6 +288,15 @@ void REPL::IOHandlerInputComplete(IOHandler &io_handler, std::string &code) {
257288
}
258289
}
259290
} else {
291+
if (code[0] == '<') {
292+
// User wants to read code from a file.
293+
// Interpret rest of line as a literal path.
294+
auto path = llvm::StringRef(code.substr(1)).trim().str();
295+
if (!ReadCode(path, code, error_sp)) {
296+
return;
297+
}
298+
}
299+
260300
// Unwind any expression we might have been running in case our REPL
261301
// expression crashed and the user was looking around
262302
if (m_dedicated_repl_mode) {

0 commit comments

Comments
 (0)