From e909fb2179724b5619213520ca46cc31b4e6713b Mon Sep 17 00:00:00 2001 From: Robin Haberkorn Date: Thu, 20 Nov 2014 05:08:19 +0100 Subject: Throw error when a macro terminates while a local q-reg is edited. This is only a problem if the macro created the local Q-Register table (i.e. not when called with ":M") but resulted in segfaults. Since we do not want to save in a Q-Reg whether it is local (and that wouldn't suffice anyway), we do it in the Q-Register table cleanup. The corresponding QRegisterTable::clear() must be called explicitly, since the RBTree::clear() called on destruction does not and cannot throw errors. If QRegisterTable::clear() has been called successfully, the default object destructor will not do much. If it has thrown an error, the destructor will clean up the remaining Q-Registers. --- src/qregisters.cpp | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) (limited to 'src/qregisters.cpp') diff --git a/src/qregisters.cpp b/src/qregisters.cpp index fdb804b..223a707 100644 --- a/src/qregisters.cpp +++ b/src/qregisters.cpp @@ -275,6 +275,30 @@ QRegisterTable::edit(QRegister *reg) QRegisters::current = reg; } +/* + * This is similar to RBTree::clear() but + * has the advantage that we can check whether some + * register is currently edited. + * Since this is not a destructor, we can throw + * errors. + * Therefore this method should be called before + * a (local) QRegisterTable is deleted. + */ +void +QRegisterTable::clear(void) +{ + QRegister *cur; + + while ((cur = (QRegister *)min())) { + if (cur == QRegisters::current) + throw Error("Currently edited Q-Register \"%s\" " + "cannot be discarded", cur->name); + + remove(cur); + delete cur; + } +} + void QRegisterStack::UndoTokenPush::run(void) { -- cgit v1.2.3