aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Burdette <bburdette@protonmail.com>2022-06-02 10:26:46 -0600
committerBen Burdette <bburdette@protonmail.com>2022-06-02 10:26:46 -0600
commit9151dbff88fa765496e970aee2db5a8ce640b3a4 (patch)
tree50ff23ee4947500872d8972195a3e5dae05e7004
parent1892355766af57868f74a9efd75aa279b29a04f6 (diff)
ignore-try flag
-rw-r--r--src/libcmd/command.cc11
-rw-r--r--src/libcmd/command.hh1
-rw-r--r--src/libexpr/eval.cc1
-rw-r--r--src/libexpr/eval.hh1
-rw-r--r--src/libexpr/primops.cc14
5 files changed, 27 insertions, 1 deletions
diff --git a/src/libcmd/command.cc b/src/libcmd/command.cc
index 7f8072d75..940fd5b23 100644
--- a/src/libcmd/command.cc
+++ b/src/libcmd/command.cc
@@ -91,6 +91,12 @@ EvalCommand::EvalCommand()
.description = "start an interactive environment if evaluation fails",
.handler = {&startReplOnEvalErrors, true},
});
+
+ addFlag({
+ .longName = "ignore-try",
+ .description = "ignore exceptions in try clauses during debug",
+ .handler = {&ignoreExceptionsDuringTry, true},
+ });
}
EvalCommand::~EvalCommand()
@@ -120,7 +126,10 @@ ref<EvalState> EvalCommand::getEvalState()
;
if (startReplOnEvalErrors) {
- evalState->debugRepl = &runRepl;
+ evalState->debugRepl = &runRepl;
+ };
+ if (ignoreExceptionsDuringTry) {
+ evalState->ignoreTry = ignoreExceptionsDuringTry;
};
}
return ref<EvalState>(evalState);
diff --git a/src/libcmd/command.hh b/src/libcmd/command.hh
index 8982f21d0..2c930dcb7 100644
--- a/src/libcmd/command.hh
+++ b/src/libcmd/command.hh
@@ -58,6 +58,7 @@ struct CopyCommand : virtual StoreCommand
struct EvalCommand : virtual StoreCommand, MixEvalArgs
{
bool startReplOnEvalErrors = false;
+ bool ignoreExceptionsDuringTry = false;
EvalCommand();
diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc
index 40462afdf..c35527992 100644
--- a/src/libexpr/eval.cc
+++ b/src/libexpr/eval.cc
@@ -467,6 +467,7 @@ EvalState::EvalState(
, debugRepl(0)
, debugStop(false)
, debugQuit(false)
+ , ignoreTry(false)
, regexCache(makeRegexCache())
#if HAVE_BOEHMGC
, valueAllocCache(std::allocate_shared<void *>(traceable_allocator<void *>(), nullptr))
diff --git a/src/libexpr/eval.hh b/src/libexpr/eval.hh
index 7b8732169..3c3dddd1e 100644
--- a/src/libexpr/eval.hh
+++ b/src/libexpr/eval.hh
@@ -130,6 +130,7 @@ public:
void (* debugRepl)(ref<EvalState> es, const ValMap & extraEnv);
bool debugStop;
bool debugQuit;
+ bool ignoreTry;
std::list<DebugTrace> debugTraces;
std::map<const Expr*, const std::shared_ptr<const StaticEnv>> exprEnvs;
const std::shared_ptr<const StaticEnv> getStaticEnv(const Expr & expr) const
diff --git a/src/libexpr/primops.cc b/src/libexpr/primops.cc
index eea274301..772898932 100644
--- a/src/libexpr/primops.cc
+++ b/src/libexpr/primops.cc
@@ -851,6 +851,15 @@ static RegisterPrimOp primop_floor({
static void prim_tryEval(EvalState & state, const PosIdx pos, Value * * args, Value & v)
{
auto attrs = state.buildBindings(2);
+
+ void (* savedDebugRepl)(ref<EvalState> es, const ValMap & extraEnv) = nullptr;
+ if (state.debugRepl && state.ignoreTry)
+ {
+ // to prevent starting the repl from exceptions withing a tryEval, null it.
+ savedDebugRepl = state.debugRepl;
+ state.debugRepl = nullptr;
+ }
+
try {
state.forceValue(*args[0], pos);
attrs.insert(state.sValue, args[0]);
@@ -859,6 +868,11 @@ static void prim_tryEval(EvalState & state, const PosIdx pos, Value * * args, Va
attrs.alloc(state.sValue).mkBool(false);
attrs.alloc("success").mkBool(false);
}
+
+ // restore the debugRepl pointer if we saved it earlier.
+ if (savedDebugRepl)
+ state.debugRepl = savedDebugRepl;
+
v.mkAttrs(attrs);
}