aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorRobin Haberkorn <robin.haberkorn@googlemail.com>2012-11-11 04:03:14 +0100
committerRobin Haberkorn <robin.haberkorn@googlemail.com>2012-11-11 04:03:14 +0100
commit46316ece115c100a8146303957a3bec07a1d2dde (patch)
tree9486c8e0a2b623a7db36af8840cfce5a489e2b90
parentd6593762d97bf44f3a398dc4fae714a9e20a24b2 (diff)
downloadsciteco-46316ece115c100a8146303957a3bec07a1d2dde.tar.gz
Q-Register table and EQx command
-rw-r--r--main.cpp1
-rw-r--r--parser.cpp17
-rw-r--r--parser.h22
-rw-r--r--qbuffers.cpp49
-rw-r--r--qbuffers.h101
-rw-r--r--rbtree.h4
6 files changed, 188 insertions, 6 deletions
diff --git a/main.cpp b/main.cpp
index 0f62dc5..fc18791 100644
--- a/main.cpp
+++ b/main.cpp
@@ -152,6 +152,7 @@ main(int argc, char **argv)
editor_msg(SCI_STYLESETFORE, SCE_C_STRING, 0x800080);
editor_msg(SCI_STYLESETBOLD, SCE_C_OPERATOR, 1);
+ qregisters.initialize();
ring.edit(NULL);
undo.enabled = true;
diff --git a/parser.cpp b/parser.cpp
index 18decd1..b3733d6 100644
--- a/parser.cpp
+++ b/parser.cpp
@@ -168,6 +168,22 @@ StateExpectString::custom(gchar chr)
return this;
}
+StateExpectQReg::StateExpectQReg() : State()
+{
+ transitions['\0'] = this;
+}
+
+State *
+StateExpectQReg::custom(gchar chr)
+{
+ QRegister *reg = qregisters[(gchar []){g_ascii_toupper(chr), '\0'}];
+
+ if (!reg)
+ return NULL;
+
+ return got_register(reg);
+}
+
StateStart::StateStart() : State()
{
transitions['\0'] = this;
@@ -563,6 +579,7 @@ StateECommand::StateECommand() : State()
{
transitions['\0'] = this;
transitions['B'] = &States::file;
+ transitions['Q'] = &States::eqcommand;
}
State *
diff --git a/parser.h b/parser.h
index 91ee036..be72249 100644
--- a/parser.h
+++ b/parser.h
@@ -49,7 +49,7 @@ public:
StateExpectString() : State() {}
private:
- virtual State *custom(gchar chr);
+ State *custom(gchar chr);
protected:
virtual void initial(void) {}
@@ -57,6 +57,26 @@ protected:
virtual State *done(const gchar *str) = 0;
};
+class QRegister;
+
+/*
+ * Super class for states accepting Q-Register specifications
+ */
+class StateExpectQReg : public State {
+public:
+ StateExpectQReg();
+
+private:
+ State *custom(gchar chr);
+
+protected:
+ /*
+ * FIXME: would be nice to pass reg as reference, but there are
+ * circular header dependencies...
+ */
+ virtual State *got_register(QRegister *reg) = 0;
+};
+
class StateStart : public State {
public:
StateStart();
diff --git a/qbuffers.cpp b/qbuffers.cpp
index d9eba9f..c907330 100644
--- a/qbuffers.cpp
+++ b/qbuffers.cpp
@@ -16,10 +16,34 @@
#include "qbuffers.h"
namespace States {
- StateFile file;
+ StateFile file;
+ StateEQCommand eqcommand;
}
Ring ring;
+QRegisterTable qregisters;
+
+void
+QRegisterTable::initialize(void)
+{
+ /* general purpose registers */
+ for (gchar q = 'A'; q <= 'Z'; q++)
+ initialize_register((gchar []){q, '\0'});
+ for (gchar q = '0'; q <= '9'; q++)
+ initialize_register((gchar []){q, '\0'});
+}
+
+void
+QRegisterTable::edit(QRegister *reg)
+{
+ if (current)
+ current->dot = editor_msg(SCI_GETCURRENTPOS);
+
+ reg->edit();
+
+ ring.current = NULL;
+ current = reg;
+}
bool
Buffer::load(const gchar *filename)
@@ -106,6 +130,7 @@ Ring::edit(const gchar *filename)
}
}
+ qregisters.current = NULL;
current = buffer;
return new_in_ring;
@@ -139,7 +164,10 @@ Ring::~Ring()
void
StateFile::do_edit(const gchar *filename)
{
- ring.undo_edit();
+ if (ring.current)
+ ring.undo_edit();
+ else /* qregisters.current != NULL */
+ qregisters.undo_edit();
if (ring.edit(filename))
ring.undo_close();
}
@@ -203,3 +231,20 @@ StateFile::done(const gchar *str)
return &States::start;
}
+
+/*
+ * TODO: expect filename to read into Q-register
+ */
+State *
+StateEQCommand::got_register(QRegister *reg)
+{
+ BEGIN_EXEC(&States::start);
+
+ if (ring.current)
+ ring.undo_edit();
+ else /* qregisters.current != NULL */
+ qregisters.undo_edit();
+ qregisters.edit(reg);
+
+ return &States::start;
+}
diff --git a/qbuffers.h b/qbuffers.h
index 56580c4..6a120e7 100644
--- a/qbuffers.h
+++ b/qbuffers.h
@@ -11,8 +11,101 @@
#include "sciteco.h"
#include "undo.h"
+#include "rbtree.h"
#include "parser.h"
+class QRegister : public RBTree::RBEntry {
+public:
+ gchar *name;
+
+ gint64 integer;
+
+ typedef void document;
+ document *string;
+ gint dot;
+
+ QRegister(const gchar *_name)
+ : name(g_strdup(_name)), integer(0), string(NULL), dot(0) {}
+ ~QRegister()
+ {
+ if (string)
+ editor_msg(SCI_RELEASEDOCUMENT, 0, (sptr_t)string);
+ g_free(name);
+ }
+
+ int
+ operator <(RBEntry &entry)
+ {
+ return g_strcmp0(name, ((QRegister &)entry).name);
+ }
+
+ inline document *
+ get_string(void)
+ {
+ if (!string)
+ string = (document *)editor_msg(SCI_CREATEDOCUMENT);
+ return string;
+ }
+
+ inline void
+ edit(void)
+ {
+ editor_msg(SCI_SETDOCPOINTER, 0, (sptr_t)get_string());
+ editor_msg(SCI_GOTOPOS, dot);
+ }
+ inline void
+ undo_edit(void)
+ {
+ undo.push_msg(SCI_GOTOPOS, dot);
+ undo.push_msg(SCI_SETDOCPOINTER, 0, (sptr_t)get_string());
+ }
+};
+
+extern class QRegisterTable : public RBTree {
+ inline void
+ initialize_register(const gchar *name)
+ {
+ QRegister *reg = new QRegister(name);
+ insert(reg);
+ /* make sure document is initialized */
+ reg->get_string();
+ }
+
+public:
+ QRegister *current;
+
+ QRegisterTable() : RBTree(), current(NULL) {}
+
+ void initialize(void);
+
+ inline QRegister *
+ operator [](const gchar *name)
+ {
+ QRegister reg(name);
+ return (QRegister *)find(&reg);
+ }
+
+ void edit(QRegister *reg);
+ inline QRegister *
+ edit(const gchar *name)
+ {
+ QRegister *reg = operator [](name);
+
+ if (!reg)
+ return NULL;
+ edit(reg);
+ return reg;
+ }
+ inline void
+ undo_edit(void)
+ {
+ current->dot = editor_msg(SCI_GETCURRENTPOS);
+
+ undo.push_var<QRegister*>(current);
+ current->undo_edit();
+ }
+} qregisters;
+
class Buffer {
class UndoTokenClose : public UndoToken {
Buffer *buffer;
@@ -136,8 +229,14 @@ private:
State *done(const gchar *str);
};
+class StateEQCommand : public StateExpectQReg {
+private:
+ State *got_register(QRegister *reg);
+};
+
namespace States {
- extern StateFile file;
+ extern StateFile file;
+ extern StateEQCommand eqcommand;
}
/*
diff --git a/rbtree.h b/rbtree.h
index 6c54f92..f4831ce 100644
--- a/rbtree.h
+++ b/rbtree.h
@@ -8,7 +8,7 @@
#include "undo.h"
class RBTree {
-protected:
+public:
class RBEntry;
private:
@@ -16,7 +16,7 @@ private:
RB_PROTOTYPE_INTERNAL(Tree, RBEntry, nodes, /* unused */, static);
-protected:
+public:
class RBEntry {
public:
RB_ENTRY(RBEntry) nodes;