diff options
author | eldritch horrors <pennae@lix.systems> | 2024-03-08 09:19:15 +0100 |
---|---|---|
committer | eldritch horrors <pennae@lix.systems> | 2024-03-09 10:17:26 -0700 |
commit | 992d99592f1022593e4df276e39e8f4f65822f74 (patch) | |
tree | 4d688284a84b4dea63c447d7283af0b30e201cf0 /src/libexpr | |
parent | 6b11c2cd7020869b796dc8e6904b358c9e41a23c (diff) |
`:quit` in the debugger should quit the whole program
(cherry picked from commit 2a8fe9a93837733e9dd9ed5c078734a35b203e14)
Change-Id: I71dadfef6b24d9272b206e9e2c408040559d8a1c
Diffstat (limited to 'src/libexpr')
-rw-r--r-- | src/libexpr/eval.cc | 14 | ||||
-rw-r--r-- | src/libexpr/eval.hh | 5 | ||||
-rw-r--r-- | src/libexpr/primops.cc | 11 | ||||
-rw-r--r-- | src/libexpr/repl-exit-status.hh | 20 |
4 files changed, 35 insertions, 15 deletions
diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index ba9fe9c65..e15781404 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -3,6 +3,7 @@ #include "hash.hh" #include "primops.hh" #include "print-options.hh" +#include "shared.hh" #include "types.hh" #include "util.hh" #include "store-api.hh" @@ -391,7 +392,6 @@ EvalState::EvalState( , buildStore(buildStore ? buildStore : store) , debugRepl(nullptr) , debugStop(false) - , debugQuit(false) , trylevel(0) , regexCache(makeRegexCache()) #if HAVE_BOEHMGC @@ -798,7 +798,17 @@ void EvalState::runDebugRepl(const Error * error, const Env & env, const Expr & auto se = getStaticEnv(expr); if (se) { auto vm = mapStaticEnvBindings(symbols, *se.get(), env); - (debugRepl)(ref<EvalState>(shared_from_this()), *vm); + auto exitStatus = (debugRepl)(ref<EvalState>(shared_from_this()), *vm); + switch (exitStatus) { + case ReplExitStatus::QuitAll: + if (error) + throw *error; + throw Exit(0); + case ReplExitStatus::Continue: + break; + default: + abort(); + } } } diff --git a/src/libexpr/eval.hh b/src/libexpr/eval.hh index 135e5fecb..5cdf34a47 100644 --- a/src/libexpr/eval.hh +++ b/src/libexpr/eval.hh @@ -11,6 +11,7 @@ #include "experimental-features.hh" #include "input-accessor.hh" #include "search-path.hh" +#include "repl-exit-status.hh" #include <map> #include <optional> @@ -207,9 +208,8 @@ public: /** * Debugger */ - void (* debugRepl)(ref<EvalState> es, const ValMap & extraEnv); + ReplExitStatus (* debugRepl)(ref<EvalState> es, const ValMap & extraEnv); bool debugStop; - bool debugQuit; int trylevel; std::list<DebugTrace> debugTraces; std::map<const Expr*, const std::shared_ptr<const StaticEnv>> exprEnvs; @@ -753,7 +753,6 @@ struct DebugTraceStacker { DebugTraceStacker(EvalState & evalState, DebugTrace t); ~DebugTraceStacker() { - // assert(evalState.debugTraces.front() == trace); evalState.debugTraces.pop_front(); } EvalState & evalState; diff --git a/src/libexpr/primops.cc b/src/libexpr/primops.cc index 86db527f6..30933e191 100644 --- a/src/libexpr/primops.cc +++ b/src/libexpr/primops.cc @@ -754,15 +754,6 @@ static RegisterPrimOp primop_break({ auto & dt = state.debugTraces.front(); state.runDebugRepl(&error, dt.env, dt.expr); - - if (state.debugQuit) { - // If the user elects to quit the repl, throw an exception. - throw Error(ErrorInfo{ - .level = lvlInfo, - .msg = HintFmt("quit the debugger"), - .pos = nullptr, - }); - } } // Return the value we were passed. @@ -873,7 +864,7 @@ static void prim_tryEval(EvalState & state, const PosIdx pos, Value * * args, Va /* increment state.trylevel, and decrement it when this function returns. */ MaintainCount trylevel(state.trylevel); - void (* savedDebugRepl)(ref<EvalState> es, const ValMap & extraEnv) = nullptr; + ReplExitStatus (* savedDebugRepl)(ref<EvalState> es, const ValMap & extraEnv) = nullptr; if (state.debugRepl && evalSettings.ignoreExceptionsDuringTry) { /* to prevent starting the repl from exceptions withing a tryEval, null it. */ diff --git a/src/libexpr/repl-exit-status.hh b/src/libexpr/repl-exit-status.hh new file mode 100644 index 000000000..08299ff61 --- /dev/null +++ b/src/libexpr/repl-exit-status.hh @@ -0,0 +1,20 @@ +#pragma once + +namespace nix { + +/** + * Exit status returned from the REPL. + */ +enum class ReplExitStatus { + /** + * The user exited with `:quit`. The program (e.g., if the REPL was acting + * as the debugger) should exit. + */ + QuitAll, + /** + * The user exited with `:continue`. The program should continue running. + */ + Continue, +}; + +} |