aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--src/parser.cpp69
-rw-r--r--src/parser.h15
2 files changed, 39 insertions, 45 deletions
diff --git a/src/parser.cpp b/src/parser.cpp
index 140a0a7..6fefe80 100644
--- a/src/parser.cpp
+++ b/src/parser.cpp
@@ -240,9 +240,20 @@ State::get_next_state(gchar chr) throw (Error, ReplaceCmdline)
return next;
}
+void
+StringBuildingMachine::reset(void)
+{
+ MicroStateMachine::reset();
+ undo.push_obj(qregspec_machine) = NULL;
+ undo.push_var(mode) = MODE_NORMAL;
+ undo.push_var(toctl) = false;
+}
+
gchar *
StringBuildingMachine::input(gchar chr) throw (State::Error)
{
+ QRegister *reg;
+
switch (mode) {
case MODE_UPPER:
chr = g_ascii_toupper(chr);
@@ -299,8 +310,14 @@ StateUpper:
StateCtlE:
switch (g_ascii_toupper(chr)) {
- case 'Q': set(&&StateCtlEQ); break;
- case 'U': set(&&StateCtlEU); break;
+ case 'Q':
+ undo.push_obj(qregspec_machine) = new QRegSpecMachine;
+ set(&&StateCtlEQ);
+ break;
+ case 'U':
+ undo.push_obj(qregspec_machine) = new QRegSpecMachine;
+ set(&&StateCtlEU);
+ break;
default:
set(NULL);
return g_strdup((gchar []){CTL_KEY('E'), chr, '\0'});
@@ -309,58 +326,34 @@ StateCtlE:
return NULL;
StateCtlEU:
- if (chr == '.') {
- set(&&StateCtlEULocal);
+ reg = qregspec_machine->input(chr);
+ if (!reg)
return NULL;
- } else {
- QRegister *reg;
-
- reg = QRegisters::globals[g_ascii_toupper(chr)];
- if (!reg)
- throw State::InvalidQRegError(chr);
- set(NULL);
- return g_strdup(CHR2STR(reg->get_integer()));
- }
-
-StateCtlEULocal: {
- QRegister *reg;
- reg = (*QRegisters::locals)[g_ascii_toupper(chr)];
- if (!reg)
- throw State::InvalidQRegError(chr, true);
+ undo.push_obj(qregspec_machine) = NULL;
set(NULL);
return g_strdup(CHR2STR(reg->get_integer()));
-}
StateCtlEQ:
- if (chr == '.') {
- set(&&StateCtlEQLocal);
+ reg = qregspec_machine->input(chr);
+ if (!reg)
return NULL;
- } else {
- QRegister *reg;
-
- reg = QRegisters::globals[g_ascii_toupper(chr)];
- if (!reg)
- throw State::InvalidQRegError(chr);
- set(NULL);
- return reg->get_string();
- }
-StateCtlEQLocal: {
- QRegister *reg;
-
- reg = (*QRegisters::locals)[g_ascii_toupper(chr)];
- if (!reg)
- throw State::InvalidQRegError(chr, true);
+ undo.push_obj(qregspec_machine) = NULL;
set(NULL);
return reg->get_string();
-}
StateEscaped:
set(NULL);
return g_strdup(CHR2STR(chr));
}
+StringBuildingMachine::~StringBuildingMachine()
+{
+ if (qregspec_machine)
+ delete qregspec_machine;
+}
+
State *
StateExpectString::custom(gchar chr) throw (Error)
{
diff --git a/src/parser.h b/src/parser.h
index 26cd064..7ef6329 100644
--- a/src/parser.h
+++ b/src/parser.h
@@ -135,7 +135,12 @@ public:
virtual Type input(gchar chr) throw (State::Error) = 0;
};
+/* avoid circular dependency on qregisters.h */
+class QRegSpecMachine;
+
class StringBuildingMachine : public MicroStateMachine<gchar *> {
+ QRegSpecMachine *qregspec_machine;
+
enum Mode {
MODE_NORMAL,
MODE_UPPER,
@@ -146,15 +151,11 @@ class StringBuildingMachine : public MicroStateMachine<gchar *> {
public:
StringBuildingMachine() : MicroStateMachine(),
+ qregspec_machine(NULL),
mode(MODE_NORMAL), toctl(false) {}
+ ~StringBuildingMachine();
- void
- reset(void)
- {
- MicroStateMachine::reset();
- undo.push_var(mode) = MODE_NORMAL;
- undo.push_var(toctl) = false;
- }
+ void reset(void);
gchar *input(gchar chr) throw (State::Error);
};