[Lldb-commits] [PATCH] D87640: Add '<' meta command to read in code from external file
pcbeard created this revision. pcbeard added reviewers: jingham, teemperor. pcbeard created this object with visibility "All Users". pcbeard added a project: LLDB. Herald added a subscriber: JDevlieghere. pcbeard requested review of this revision. Perform all error handling in ReadCode() Add :help text describing “< path”, add extra line before Commands Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D87640 Files: lldb/source/Expression/REPL.cpp Index: lldb/source/Expression/REPL.cpp === --- lldb/source/Expression/REPL.cpp +++ lldb/source/Expression/REPL.cpp @@ -123,10 +123,11 @@ "Valid statements, expressions, and declarations are immediately " "compiled and executed.\n\n" "The complete set of LLDB debugging commands are also available as " - "described below. Commands " + "described below.\n\nCommands " "must be prefixed with a colon at the REPL prompt (:quit for " "example.) Typing just a colon " - "followed by return will switch to the LLDB prompt.\n\n"; + "followed by return will switch to the LLDB prompt.\n\n" + "Type “< path” to read in code from a text file “path”.\n\n"; } bool REPL::IOHandlerIsInputComplete(IOHandler &io_handler, StringList &lines) { @@ -179,6 +180,36 @@ return (int)desired_indent - actual_indent; } +static bool ReadCode(const std::string &path, std::string &code, + lldb::StreamFileSP &error_sp) { + auto &fs = FileSystem::Instance(); + llvm::Twine pathTwine(path); + if (!fs.Exists(pathTwine)) { +error_sp->Printf("no such file at path '%s'\n", path.c_str()); +return false; + } + if (!fs.Readable(pathTwine)) { +error_sp->Printf("could not read file at path '%s'\n", path.c_str()); +return false; + } + const size_t file_size = fs.GetByteSize(pathTwine); + const size_t max_size = code.max_size(); + if (file_size > max_size) { +error_sp->Printf("file at path '%s' too large: " + "file_size = %llu, max_size = %llu\n", + path.c_str(), file_size, max_size); +return false; + } + auto data_sp = fs.CreateDataBuffer(pathTwine); + if (data_sp == nullptr) { +error_sp->Printf("could not create buffer for " + "file at path '%s'\n", path.c_str()); +return false; + } + code.assign((const char *)data_sp->GetBytes(), data_sp->GetByteSize()); + return true; +} + void REPL::IOHandlerInputComplete(IOHandler &io_handler, std::string &code) { lldb::StreamFileSP output_sp(io_handler.GetOutputStreamFileSP()); lldb::StreamFileSP error_sp(io_handler.GetErrorStreamFileSP()); @@ -257,6 +288,14 @@ } } } else { + if (code[0] == '<') { +// user wants to read code from a file. interpret rest of line as a literal path +auto path = llvm::StringRef(code.substr(1)).trim().str(); +if (!ReadCode(path, code, error_sp)) { + return; +} + } + // Unwind any expression we might have been running in case our REPL // expression crashed and the user was looking around if (m_dedicated_repl_mode) { Index: lldb/source/Expression/REPL.cpp === --- lldb/source/Expression/REPL.cpp +++ lldb/source/Expression/REPL.cpp @@ -123,10 +123,11 @@ "Valid statements, expressions, and declarations are immediately " "compiled and executed.\n\n" "The complete set of LLDB debugging commands are also available as " - "described below. Commands " + "described below.\n\nCommands " "must be prefixed with a colon at the REPL prompt (:quit for " "example.) Typing just a colon " - "followed by return will switch to the LLDB prompt.\n\n"; + "followed by return will switch to the LLDB prompt.\n\n" + "Type â< pathâ to read in code from a text file âpathâ.\n\n"; } bool REPL::IOHandlerIsInputComplete(IOHandler &io_handler, StringList &lines) { @@ -179,6 +180,36 @@ return (int)desired_indent - actual_indent; } +static bool ReadCode(const std::string &path, std::string &code, + lldb::StreamFileSP &error_sp) { + auto &fs = FileSystem::Instance(); + llvm::Twine pathTwine(path); + if (!fs.Exists(pathTwine)) { +error_sp->Printf("no such file at path '%s'\n", path.c_str()); +return false; + } + if (!fs.Readable(pathTwine)) { +error_sp->Printf("could not read file at path '%s'\n", path.c_str()); +return false; + } + const size_t file_size = fs.GetByteSize(pathTwine); + const size_t max_size = code.max_size(); + if (file_size > max_size) { +error_sp->Printf("file at path '%s' too large: " + "file_size = %llu, max_size = %llu\n", + path.c_str(), file_size, max_size); +return false; + } + auto data_
[Lldb-commits] [PATCH] D87640: Add '<' meta command to read in code from external file
pcbeard updated this revision to Diff 291742. pcbeard added a comment. Reformatted whitespace. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D87640/new/ https://reviews.llvm.org/D87640 Files: lldb/source/Expression/REPL.cpp Index: lldb/source/Expression/REPL.cpp === --- lldb/source/Expression/REPL.cpp +++ lldb/source/Expression/REPL.cpp @@ -123,10 +123,11 @@ "Valid statements, expressions, and declarations are immediately " "compiled and executed.\n\n" "The complete set of LLDB debugging commands are also available as " - "described below. Commands " + "described below.\n\nCommands " "must be prefixed with a colon at the REPL prompt (:quit for " "example.) Typing just a colon " - "followed by return will switch to the LLDB prompt.\n\n"; + "followed by return will switch to the LLDB prompt.\n\n" + "Type “< path” to read in code from a text file “path”.\n\n"; } bool REPL::IOHandlerIsInputComplete(IOHandler &io_handler, StringList &lines) { @@ -179,6 +180,36 @@ return (int)desired_indent - actual_indent; } +static bool ReadCode(const std::string &path, std::string &code, + lldb::StreamFileSP &error_sp) { + auto &fs = FileSystem::Instance(); + llvm::Twine pathTwine(path); + if (!fs.Exists(pathTwine)) { +error_sp->Printf("no such file at path '%s'\n", path.c_str()); +return false; + } + if (!fs.Readable(pathTwine)) { +error_sp->Printf("could not read file at path '%s'\n", path.c_str()); +return false; + } + const size_t file_size = fs.GetByteSize(pathTwine); + const size_t max_size = code.max_size(); + if (file_size > max_size) { +error_sp->Printf("file at path '%s' too large: " + "file_size = %llu, max_size = %llu\n", + path.c_str(), file_size, max_size); +return false; + } + auto data_sp = fs.CreateDataBuffer(pathTwine); + if (data_sp == nullptr) { +error_sp->Printf("could not create buffer for file at path '%s'\n", + path.c_str()); +return false; + } + code.assign((const char *)data_sp->GetBytes(), data_sp->GetByteSize()); + return true; +} + void REPL::IOHandlerInputComplete(IOHandler &io_handler, std::string &code) { lldb::StreamFileSP output_sp(io_handler.GetOutputStreamFileSP()); lldb::StreamFileSP error_sp(io_handler.GetErrorStreamFileSP()); @@ -257,6 +288,15 @@ } } } else { + if (code[0] == '<') { +// User wants to read code from a file. +// Interpret rest of line as a literal path. +auto path = llvm::StringRef(code.substr(1)).trim().str(); +if (!ReadCode(path, code, error_sp)) { + return; +} + } + // Unwind any expression we might have been running in case our REPL // expression crashed and the user was looking around if (m_dedicated_repl_mode) { Index: lldb/source/Expression/REPL.cpp === --- lldb/source/Expression/REPL.cpp +++ lldb/source/Expression/REPL.cpp @@ -123,10 +123,11 @@ "Valid statements, expressions, and declarations are immediately " "compiled and executed.\n\n" "The complete set of LLDB debugging commands are also available as " - "described below. Commands " + "described below.\n\nCommands " "must be prefixed with a colon at the REPL prompt (:quit for " "example.) Typing just a colon " - "followed by return will switch to the LLDB prompt.\n\n"; + "followed by return will switch to the LLDB prompt.\n\n" + "Type â< pathâ to read in code from a text file âpathâ.\n\n"; } bool REPL::IOHandlerIsInputComplete(IOHandler &io_handler, StringList &lines) { @@ -179,6 +180,36 @@ return (int)desired_indent - actual_indent; } +static bool ReadCode(const std::string &path, std::string &code, + lldb::StreamFileSP &error_sp) { + auto &fs = FileSystem::Instance(); + llvm::Twine pathTwine(path); + if (!fs.Exists(pathTwine)) { +error_sp->Printf("no such file at path '%s'\n", path.c_str()); +return false; + } + if (!fs.Readable(pathTwine)) { +error_sp->Printf("could not read file at path '%s'\n", path.c_str()); +return false; + } + const size_t file_size = fs.GetByteSize(pathTwine); + const size_t max_size = code.max_size(); + if (file_size > max_size) { +error_sp->Printf("file at path '%s' too large: " + "file_size = %llu, max_size = %llu\n", + path.c_str(), file_size, max_size); +return false; + } + auto data_sp = fs.CreateDataBuffer(pathTwine); + if (data_sp == nullptr) { +error_sp->Printf("could not create buffer for file at path '%s'\n", + path.c_str()); +return