diff options
author | Robin Haberkorn <robin.haberkorn@googlemail.com> | 2015-07-14 15:32:48 +0200 |
---|---|---|
committer | Robin Haberkorn <robin.haberkorn@googlemail.com> | 2015-07-14 15:32:48 +0200 |
commit | 7a851424152a942443190ac34856c08d8dfe7580 (patch) | |
tree | ce9d234d60934e1cb5fbc20fcc1f6e6b677b492d /src/qregisters.cpp | |
parent | 45e2f9a5c6a8ac29ce9fa1bf2e18343098c4a050 (diff) | |
download | sciteco-7a851424152a942443190ac34856c08d8dfe7580.tar.gz |
fixed error message for Qq if <q> does not exist
* the problem comes from StateExpectQReg resetting the QRegMachine
too early. StateExpectQReg(QREG_OPTIONAL) states cannot call
machine.fail() in their got_register() callback.
In other words, commands with both optional or required registers
depending on runtime state cannot be modelled with StateExpectQReg.
* instead we derive from State directly - most functionality is
encapsulated in QRegSpecMachine anyway.
* might also fix crashes on some systems.
Diffstat (limited to 'src/qregisters.cpp')
-rw-r--r-- | src/qregisters.cpp | 33 |
1 files changed, 28 insertions, 5 deletions
diff --git a/src/qregisters.cpp b/src/qregisters.cpp index e47415b..b7ef0c1 100644 --- a/src/qregisters.cpp +++ b/src/qregisters.cpp @@ -900,8 +900,13 @@ StateExpectQReg::custom(gchar chr) if (!machine.input(chr, reg)) return this; - machine.reset(); + /* + * NOTE: We must reset the Q-Reg machine + * now, since we have commands like <M> + * that indirectly call their state recursively. + */ + machine.reset(); return got_register(reg); } @@ -1050,10 +1055,22 @@ StateSaveQReg::got_file(const gchar *filename) * If <q> is undefined, it returns \fIsuccess\fP, else a \fIfailure\fP * boolean. */ +StateQueryQReg::StateQueryQReg() : machine(QREG_OPTIONAL) +{ + transitions['\0'] = this; +} + State * -StateQueryQReg::got_register(QRegister *reg) +StateQueryQReg::custom(gchar chr) { - BEGIN_EXEC(&States::start); + QRegister *reg; + + if (!machine.input(chr, reg)) + return this; + + /* like BEGIN_EXEC(&States::start), but resets machine */ + if (mode > MODE_NORMAL) + goto reset; expressions.eval(); @@ -1061,7 +1078,7 @@ StateQueryQReg::got_register(QRegister *reg) /* Query Q-Register's existence or string size */ expressions.push(reg ? reg->get_string_size() : (tecoInt)-1); - return &States::start; + goto reset; } /* @@ -1069,7 +1086,11 @@ StateQueryQReg::got_register(QRegister *reg) * without colon and otherwise optional. * While it may be clearer to model this as two States, * we cannot currently let parsing depend on the colon-modifier. - * That's why we have to delegate exception throwing to QRegSpecMachine. + * That's why we have to declare the Q-Reg machine as QREG_OPTIONAL + * and care about exception throwing on our own. + * Since we need the machine's state to throw a reasonable error + * we cannot derive from StateExpectQReg since it has to reset the + * machine before calling got_register(). */ if (!reg) machine.fail(); @@ -1085,6 +1106,8 @@ StateQueryQReg::got_register(QRegister *reg) expressions.push(reg->get_integer()); } +reset: + machine.reset(); return &States::start; } |