diff options
author | Robin Haberkorn <robin.haberkorn@googlemail.com> | 2014-11-20 05:08:19 +0100 |
---|---|---|
committer | Robin Haberkorn <robin.haberkorn@googlemail.com> | 2014-11-20 05:08:19 +0100 |
commit | e909fb2179724b5619213520ca46cc31b4e6713b (patch) | |
tree | b80edd2db67783d9a44a0dc45ffbe7e0baef20fb /src/parser.cpp | |
parent | f843a090cdda120d58f968b7936bdcc53b61e323 (diff) | |
download | sciteco-e909fb2179724b5619213520ca46cc31b4e6713b.tar.gz |
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.
Diffstat (limited to 'src/parser.cpp')
-rw-r--r-- | src/parser.cpp | 40 |
1 files changed, 26 insertions, 14 deletions
diff --git a/src/parser.cpp b/src/parser.cpp index 0b11721..35b6add 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -146,25 +146,37 @@ Execute::macro(const gchar *macro, bool locals) try { step(macro, strlen(macro)); - if (Goto::skip_label) { - Error error("Label \"%s\" not found", - Goto::skip_label); - error.pos = strlen(macro); - String::get_coord(macro, error.pos, - error.line, error.column); - throw error; - } + /* + * Subsequent errors must still be + * attached to this macro invocation. + */ + try { + if (Goto::skip_label) + throw Error("Label \"%s\" not found", + Goto::skip_label); + + if (States::current != &States::start) + /* + * can only happen if we returned because + * of macro end + */ + throw Error("Unterminated command"); - if (States::current != &States::start) { - Error error("Unterminated command"); /* - * can only happen if we returned because - * of macro end + * This handles the problem of Q-Registers + * local to the macro invocation being edited + * when the macro terminates. + * QRegisterTable::clear() throws an error + * if this happens and the Q-Reg editing + * is undone. */ + if (locals) + QRegisters::locals->clear(); + } catch (Error &error) { error.pos = strlen(macro); String::get_coord(macro, error.pos, - error.line, error.column); - throw error; + error.line, error.column); + throw; /* forward */ } } catch (...) { g_free(Goto::skip_label); |