mirror of
https://github.com/NixOS/nix
synced 2025-06-25 10:41:16 +02:00
:quit
in the debugger should quit the whole program
This commit is contained in:
parent
78e7c98b02
commit
2a8fe9a938
10 changed files with 111 additions and 44 deletions
|
@ -52,6 +52,27 @@ extern "C" {
|
|||
|
||||
namespace nix {
|
||||
|
||||
/**
|
||||
* Returned by `NixRepl::processLine`.
|
||||
*/
|
||||
enum class ProcessLineResult {
|
||||
/**
|
||||
* The user exited with `:quit`. The REPL should exit. The surrounding
|
||||
* program or evaluation (e.g., if the REPL was acting as the debugger)
|
||||
* should also exit.
|
||||
*/
|
||||
QuitAll,
|
||||
/**
|
||||
* The user exited with `:continue`. The REPL should exit, but the program
|
||||
* should continue running.
|
||||
*/
|
||||
QuitOnce,
|
||||
/**
|
||||
* The user did not exit. The REPL should request another line of input.
|
||||
*/
|
||||
Continue,
|
||||
};
|
||||
|
||||
struct NixRepl
|
||||
: AbstractNixRepl
|
||||
#if HAVE_BOEHMGC
|
||||
|
@ -75,13 +96,13 @@ struct NixRepl
|
|||
std::function<AnnotatedValues()> getValues);
|
||||
virtual ~NixRepl();
|
||||
|
||||
void mainLoop() override;
|
||||
ReplExitStatus mainLoop() override;
|
||||
void initEnv() override;
|
||||
|
||||
StringSet completePrefix(const std::string & prefix);
|
||||
bool getLine(std::string & input, const std::string & prompt);
|
||||
StorePath getDerivationPath(Value & v);
|
||||
bool processLine(std::string line);
|
||||
ProcessLineResult processLine(std::string line);
|
||||
|
||||
void loadFile(const Path & path);
|
||||
void loadFlake(const std::string & flakeRef);
|
||||
|
@ -246,7 +267,7 @@ static std::ostream & showDebugTrace(std::ostream & out, const PosTable & positi
|
|||
|
||||
static bool isFirstRepl = true;
|
||||
|
||||
void NixRepl::mainLoop()
|
||||
ReplExitStatus NixRepl::mainLoop()
|
||||
{
|
||||
if (isFirstRepl) {
|
||||
std::string_view debuggerNotice = "";
|
||||
|
@ -287,15 +308,25 @@ void NixRepl::mainLoop()
|
|||
// When continuing input from previous lines, don't print a prompt, just align to the same
|
||||
// number of chars as the prompt.
|
||||
if (!getLine(input, input.empty() ? "nix-repl> " : " ")) {
|
||||
// ctrl-D should exit the debugger.
|
||||
// Ctrl-D should exit the debugger.
|
||||
state->debugStop = false;
|
||||
state->debugQuit = true;
|
||||
logger->cout("");
|
||||
break;
|
||||
// TODO: Should Ctrl-D exit just the current debugger session or
|
||||
// the entire program?
|
||||
return ReplExitStatus::QuitAll;
|
||||
}
|
||||
logger->resume();
|
||||
try {
|
||||
if (!removeWhitespace(input).empty() && !processLine(input)) return;
|
||||
switch (processLine(input)) {
|
||||
case ProcessLineResult::QuitAll:
|
||||
return ReplExitStatus::QuitAll;
|
||||
case ProcessLineResult::QuitOnce:
|
||||
return ReplExitStatus::Continue;
|
||||
case ProcessLineResult::Continue:
|
||||
break;
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
} catch (ParseError & e) {
|
||||
if (e.msg().find("unexpected end of file") != std::string::npos) {
|
||||
// For parse errors on incomplete input, we continue waiting for the next line of
|
||||
|
@ -483,10 +514,11 @@ void NixRepl::loadDebugTraceEnv(DebugTrace & dt)
|
|||
}
|
||||
}
|
||||
|
||||
bool NixRepl::processLine(std::string line)
|
||||
ProcessLineResult NixRepl::processLine(std::string line)
|
||||
{
|
||||
line = trim(line);
|
||||
if (line == "") return true;
|
||||
if (line.empty())
|
||||
return ProcessLineResult::Continue;
|
||||
|
||||
_isInterrupted = false;
|
||||
|
||||
|
@ -581,13 +613,13 @@ bool NixRepl::processLine(std::string line)
|
|||
else if (state->debugRepl && (command == ":s" || command == ":step")) {
|
||||
// set flag to stop at next DebugTrace; exit repl.
|
||||
state->debugStop = true;
|
||||
return false;
|
||||
return ProcessLineResult::QuitOnce;
|
||||
}
|
||||
|
||||
else if (state->debugRepl && (command == ":c" || command == ":continue")) {
|
||||
// set flag to run to next breakpoint or end of program; exit repl.
|
||||
state->debugStop = false;
|
||||
return false;
|
||||
return ProcessLineResult::QuitOnce;
|
||||
}
|
||||
|
||||
else if (command == ":a" || command == ":add") {
|
||||
|
@ -730,8 +762,7 @@ bool NixRepl::processLine(std::string line)
|
|||
|
||||
else if (command == ":q" || command == ":quit") {
|
||||
state->debugStop = false;
|
||||
state->debugQuit = true;
|
||||
return false;
|
||||
return ProcessLineResult::QuitAll;
|
||||
}
|
||||
|
||||
else if (command == ":doc") {
|
||||
|
@ -792,7 +823,7 @@ bool NixRepl::processLine(std::string line)
|
|||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
return ProcessLineResult::Continue;
|
||||
}
|
||||
|
||||
void NixRepl::loadFile(const Path & path)
|
||||
|
@ -923,7 +954,7 @@ std::unique_ptr<AbstractNixRepl> AbstractNixRepl::create(
|
|||
}
|
||||
|
||||
|
||||
void AbstractNixRepl::runSimple(
|
||||
ReplExitStatus AbstractNixRepl::runSimple(
|
||||
ref<EvalState> evalState,
|
||||
const ValMap & extraEnv)
|
||||
{
|
||||
|
@ -945,7 +976,7 @@ void AbstractNixRepl::runSimple(
|
|||
for (auto & [name, value] : extraEnv)
|
||||
repl->addVarToScope(repl->state->symbols.create(name), *value);
|
||||
|
||||
repl->mainLoop();
|
||||
return repl->mainLoop();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue