aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--goto.h10
-rw-r--r--parser.cpp33
-rw-r--r--qbuffers.cpp35
-rw-r--r--qbuffers.h38
4 files changed, 80 insertions, 36 deletions
diff --git a/goto.h b/goto.h
index 146bade..6275d34 100644
--- a/goto.h
+++ b/goto.h
@@ -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
diff --git a/parser.cpp b/parser.cpp
index fb31add..04c7a3e 100644
--- a/parser.cpp
+++ b/parser.cpp
@@ -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 = &macro_goto_table;
if (locals) {
- parent_locals = QRegisters::locals;
macro_locals.initialize();
QRegisters::locals = &macro_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;
}
diff --git a/qbuffers.h b/qbuffers.h
index 3613c93..fae77f5 100644
--- a/qbuffers.h
+++ b/qbuffers.h
@@ -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)