diff options
-rw-r--r-- | goto.h | 10 | ||||
-rw-r--r-- | parser.cpp | 33 | ||||
-rw-r--r-- | qbuffers.cpp | 35 | ||||
-rw-r--r-- | qbuffers.h | 38 |
4 files changed, 80 insertions, 36 deletions
@@ -53,8 +53,13 @@ class GotoTable : public RBTree { } }; + /* + * whether to generate UndoTokens (unnecessary in macro invocations) + */ + bool must_undo; + public: - GotoTable() : RBTree() {} + GotoTable(bool _undo = true) : RBTree(), must_undo(_undo) {} gint remove(gchar *name); gint find(gchar *name); @@ -63,7 +68,8 @@ public: inline void undo_set(gchar *name, gint pc = -1) { - undo.push(new UndoTokenSet(this, name, pc)); + if (must_undo) + undo.push(new UndoTokenSet(this, name, pc)); } #ifdef DEBUG @@ -64,10 +64,10 @@ void Execute::macro(const gchar *macro, bool locals) throw (State::Error) { GotoTable *parent_goto_table = Goto::table; - GotoTable macro_goto_table; + GotoTable macro_goto_table(false); - QRegisterTable *parent_locals; - QRegisterTable macro_locals; + QRegisterTable *parent_locals = QRegisters::locals; + QRegisterTable macro_locals(false); State *parent_state = States::current; gint parent_pc = macro_pc; @@ -82,7 +82,6 @@ Execute::macro(const gchar *macro, bool locals) throw (State::Error) Goto::table = ¯o_goto_table; if (locals) { - parent_locals = QRegisters::locals; macro_locals.initialize(); QRegisters::locals = ¯o_locals; } @@ -96,10 +95,7 @@ Execute::macro(const gchar *macro, bool locals) throw (State::Error) g_free(Goto::skip_label); Goto::skip_label = NULL; - if (locals) { - delete QRegisters::locals; - QRegisters::locals = parent_locals; - } + QRegisters::locals = parent_locals; Goto::table = parent_goto_table; macro_pc = parent_pc; @@ -108,10 +104,7 @@ Execute::macro(const gchar *macro, bool locals) throw (State::Error) throw; /* forward */ } - if (locals) { - delete QRegisters::locals; - QRegisters::locals = parent_locals; - } + QRegisters::locals = parent_locals; Goto::table = parent_goto_table; macro_pc = parent_pc; @@ -279,7 +272,7 @@ StateExpectString::machine_input(gchar chr) throw (Error) reg = QRegisters::globals[g_ascii_toupper(chr)]; if (!reg) throw InvalidQRegError(chr); - return g_strdup((gchar []){(gchar)reg->integer, '\0'}); + return g_strdup(CHR2STR(reg->get_integer())); } break; @@ -290,7 +283,7 @@ StateExpectString::machine_input(gchar chr) throw (Error) reg = (*QRegisters::locals)[g_ascii_toupper(chr)]; if (!reg) throw InvalidQRegError(chr, true); - return g_strdup((gchar []){(gchar)reg->integer, '\0'}); + return g_strdup(CHR2STR(reg->get_integer())); } case Machine::STATE_CTL_EQ: @@ -697,7 +690,7 @@ StateStart::custom(gchar chr) throw (Error) case ';': BEGIN_EXEC(this); - v = QRegisters::globals["_"]->integer; + v = QRegisters::globals["_"]->get_integer(); rc = expressions.pop_num_calc(1, v); if (eval_colon()) rc = ~rc; @@ -1546,8 +1539,8 @@ StateSearch::process(const gchar *str, undo.push_msg(SCI_GOTOPOS, interface.ssm(SCI_GETCURRENTPOS)); - undo.push_var<gint64>(search_reg->integer); - search_reg->integer = FAILURE; + search_reg->undo_set_integer(); + search_reg->set_integer(FAILURE); /* NOTE: pattern2regexp() modifies str pointer */ re_pattern = pattern2regexp(str); @@ -1611,7 +1604,7 @@ StateSearch::process(const gchar *str, if (matched_from >= 0 && matched_to >= 0) { /* match success */ - search_reg->integer = SUCCESS; + search_reg->set_integer(SUCCESS); interface.ssm(SCI_SETSEL, matched_from, matched_to); } else { interface.ssm(SCI_GOTOPOS, parameters.dot); @@ -1637,8 +1630,8 @@ StateSearch::done(const gchar *str) throw (Error) } if (eval_colon()) - expressions.push(search_reg->integer); - else if (IS_FAILURE(search_reg->integer) && + expressions.push(search_reg->get_integer()); + else if (IS_FAILURE(search_reg->get_integer()) && !expressions.find_op(Expressions::OP_LOOP) /* not in loop */) interface.msg(Interface::MSG_ERROR, "Search string not found!"); diff --git a/qbuffers.cpp b/qbuffers.cpp index 4aa0c86..42ac436 100644 --- a/qbuffers.cpp +++ b/qbuffers.cpp @@ -93,6 +93,9 @@ QRegisterData::set_string(const gchar *str) void QRegisterData::undo_set_string(void) { + if (!must_undo) + return; + current_save_dot(); if (ring.current) ring.current->undo_edit(); @@ -133,6 +136,9 @@ QRegisterData::edit(void) void QRegisterData::undo_edit(void) { + if (!must_undo) + return; + undo.push_msg(SCI_GOTOPOS, dot); undo.push_msg(SCI_SETDOCPOINTER, 0, (sptr_t)get_document()); } @@ -147,6 +153,9 @@ QRegister::edit(void) void QRegister::undo_edit(void) { + if (!must_undo) + return; + interface.undo_info_update(this); QRegisterData::undo_edit(); } @@ -254,7 +263,7 @@ QRegisterStack::push(QRegister *reg) { Entry *entry = new Entry(); - entry->integer = reg->integer; + entry->set_integer(reg->get_integer()); if (reg->string) { gchar *str = reg->get_string(); entry->set_string(str); @@ -275,17 +284,19 @@ QRegisterStack::pop(QRegister *reg) if (!entry) return false; - undo.push_var(reg->integer); - reg->integer = entry->integer; + reg->undo_set_integer(); + reg->set_integer(entry->get_integer()); /* exchange document ownership between Stack entry and Q-Register */ string = reg->string; - undo.push_var(reg->string); + if (reg->must_undo) + undo.push_var(reg->string); reg->string = entry->string; undo.push_var(entry->string); entry->string = string; - undo.push_var(reg->dot); + if (reg->must_undo) + undo.push_var(reg->dot); reg->dot = entry->dot; SLIST_REMOVE_HEAD(&head, entries); @@ -813,7 +824,7 @@ StateGetQRegInteger::got_register(QRegister *reg) throw (Error) BEGIN_EXEC(&States::start); expressions.eval(); - expressions.push(reg->integer); + expressions.push(reg->get_integer()); return &States::start; } @@ -823,8 +834,8 @@ StateSetQRegInteger::got_register(QRegister *reg) throw (Error) { BEGIN_EXEC(&States::start); - undo.push_var<gint64>(reg->integer); - reg->integer = expressions.pop_num_calc(); + reg->undo_set_integer(); + reg->set_integer(expressions.pop_num_calc()); return &States::start; } @@ -832,11 +843,13 @@ StateSetQRegInteger::got_register(QRegister *reg) throw (Error) State * StateIncreaseQReg::got_register(QRegister *reg) throw (Error) { + gint64 res; + BEGIN_EXEC(&States::start); - undo.push_var<gint64>(reg->integer); - reg->integer += expressions.pop_num_calc(); - expressions.push(reg->integer); + reg->undo_set_integer(); + res = reg->get_integer() + expressions.pop_num_calc(); + expressions.push(reg->set_integer(res)); return &States::start; } @@ -31,14 +31,19 @@ gchar *get_absolute_path(const gchar *path); */ class QRegisterData { -public: gint64 integer; +public: typedef void document; document *string; gint dot; - QRegisterData() : integer(0), string(NULL), dot(0) {} + /* + * whether to generate UndoTokens (unnecessary in macro invocations) + */ + bool must_undo; + + QRegisterData() : integer(0), string(NULL), dot(0), must_undo(true) {} virtual ~QRegisterData() { @@ -54,6 +59,23 @@ public: return string; } + virtual gint64 + set_integer(gint64 i) + { + return integer = i; + } + virtual void + undo_set_integer(void) + { + if (must_undo) + undo.push_var(integer); + } + virtual gint64 + get_integer(void) + { + return integer; + } + virtual void set_string(const gchar *str); virtual void undo_set_string(void); virtual gchar *get_string(void); @@ -108,8 +130,18 @@ public: }; class QRegisterTable : public RBTree { + bool must_undo; + public: - QRegisterTable() : RBTree() {} + QRegisterTable(bool _undo = true) : RBTree(), must_undo(_undo) {} + + inline QRegister * + insert(QRegister *reg) + { + reg->must_undo = must_undo; + RBTree::insert(reg); + return reg; + } inline void initialize(const gchar *name) |