diff options
author | Robin Haberkorn <robin.haberkorn@googlemail.com> | 2012-11-20 01:57:14 +0100 |
---|---|---|
committer | Robin Haberkorn <robin.haberkorn@googlemail.com> | 2012-11-20 06:07:34 +0100 |
commit | df9f83a249e59867373e06c79aa8f57a5c9640b7 (patch) | |
tree | 1a105e4c80877b58f3b0e5dfbe418910144f1077 | |
parent | ec510eda5f080d39906c396a36cba89188031640 (diff) | |
download | sciteco-df9f83a249e59867373e06c79aa8f57a5c9640b7.tar.gz |
cleanup macro execution functions: common namespace, Execute::file() uses Execute::macro()
-rw-r--r-- | cmdline.cpp | 2 | ||||
-rw-r--r-- | main.cpp | 9 | ||||
-rw-r--r-- | parser.cpp | 89 | ||||
-rw-r--r-- | parser.h | 11 | ||||
-rw-r--r-- | qbuffers.cpp | 59 | ||||
-rw-r--r-- | qbuffers.h | 10 |
6 files changed, 86 insertions, 94 deletions
diff --git a/cmdline.cpp b/cmdline.cpp index 5d6700f..deeeed3 100644 --- a/cmdline.cpp +++ b/cmdline.cpp @@ -64,7 +64,7 @@ cmdline_keypress(gchar key) *cmdline_p = '\0'; try { - macro_execute(cmdline); + Execute::step(cmdline); } catch (...) { /* * Undo tokens may have been emitted (or had to be) @@ -100,8 +100,8 @@ process_options(int &argc, char **&argv) int main(int argc, char **argv) { - static GotoTable cmdline_goto_table; - static QRegisterTable local_qregs; + static GotoTable cmdline_goto_table; + static QRegisterTable local_qregs; process_options(argc, argv); @@ -135,9 +135,10 @@ main(int argc, char **argv) } if (g_file_test(mung_file, G_FILE_TEST_IS_REGULAR)) { - if (!file_execute(mung_file, false)) + if (!Execute::file(mung_file, false)) exit(EXIT_FAILURE); - /* FIXME: make quit immediate in commandline mode (non-UNDO)? */ + + /* FIXME: make quit immediate in batch/macro mode (non-UNDO)? */ if (quit_requested) { /* FIXME */ exit(EXIT_SUCCESS); @@ -46,7 +46,7 @@ gchar *strings[2] = {NULL, NULL}; gchar escape_char = '\x1B'; void -macro_execute(const gchar *macro) throw (State::Error) +Execute::step(const gchar *macro) throw (State::Error) { while (macro[macro_pc]) { #ifdef DEBUG @@ -60,50 +60,83 @@ macro_execute(const gchar *macro) throw (State::Error) } } -/* - * TODO: make this usable from other macro invocations as well - */ -bool -file_execute(const gchar *filename, bool locals) +void +Execute::macro(const gchar *macro, bool locals) throw (State::Error) { - gchar *macro, *p = NULL; - GotoTable file_goto_table; - QRegisterTable *parent_locals = QRegisters::locals; + GotoTable *parent_goto_table = Goto::table; + GotoTable macro_goto_table; + + QRegisterTable *parent_locals; + QRegisterTable macro_locals; + State *parent_state = States::current; + gint parent_pc = macro_pc; + + /* + * need this to fixup state on rubout: state machine emits undo token + * resetting state to parent's one, but the macro executed also emitted + * undo tokens resetting the state to StateStart + */ + undo.push_var(States::current) = &States::start; macro_pc = 0; - States::current = &States::start; - Goto::table = &file_goto_table; + Goto::table = ¯o_goto_table; if (locals) { - QRegisters::locals = new QRegisterTable(); - QRegisters::locals->initialize(); + parent_locals = QRegisters::locals; + macro_locals.initialize(); + QRegisters::locals = ¯o_locals; } - if (!g_file_get_contents(filename, ¯o, NULL, NULL)) - return false; - /* only when executing files, ignore Hash-Bang line */ - if (macro[0] == '#') - p = MAX(strchr(macro, '\r'), strchr(macro, '\n')); - try { - macro_execute(p ? p+1 : macro); + step(macro); if (Goto::skip_label) throw State::Error("Label \"%s\" not found", Goto::skip_label); } catch (...) { - g_free(macro); g_free(Goto::skip_label); Goto::skip_label = NULL; - return false; + + if (locals) { + delete QRegisters::locals; + QRegisters::locals = parent_locals; + } + Goto::table = parent_goto_table; + + macro_pc = parent_pc; + States::current = parent_state; + + throw; /* forward */ } - g_free(macro); - macro_pc = 0; - States::current = &States::start; - Goto::table = NULL; - if (locals) + if (locals) { delete QRegisters::locals; - QRegisters::locals = parent_locals; + QRegisters::locals = parent_locals; + } + Goto::table = parent_goto_table; + + macro_pc = parent_pc; + States::current = parent_state; +} + +bool +Execute::file(const gchar *filename, bool locals) +{ + gchar *macro_str, *p = NULL; + + if (!g_file_get_contents(filename, ¯o_str, NULL, NULL)) + return false; + /* only when executing files, ignore Hash-Bang line */ + if (*macro_str == '#') + p = MAX(strchr(macro_str, '\r'), strchr(macro_str, '\n')); + + try { + macro(p ? p+1 : macro_str, locals); + } catch (...) { + g_free(macro_str); + return false; + } + + g_free(macro_str); return true; } @@ -236,8 +236,6 @@ private: State *done(const gchar *str) throw (Error); }; -extern gint macro_pc; - namespace States { extern StateStart start; extern StateControl control; @@ -263,10 +261,15 @@ extern enum Mode { return STATE; \ } G_STMT_END +extern gint macro_pc; + extern gchar *strings[2]; extern gchar escape_char; -void macro_execute(const gchar *macro) throw (State::Error); -bool file_execute(const gchar *filename, bool locals = true); +namespace Execute { + void step(const gchar *macro) throw (State::Error); + void macro(const gchar *macro, bool locals = true) throw (State::Error); + bool file(const gchar *filename, bool locals = true); +} #endif diff --git a/qbuffers.cpp b/qbuffers.cpp index f58b479..4aa0c86 100644 --- a/qbuffers.cpp +++ b/qbuffers.cpp @@ -39,11 +39,17 @@ namespace States { } namespace QRegisters { - QRegisterTable globals; - QRegisterTable *locals = NULL; - QRegister *current = NULL; + QRegisterTable globals; + QRegisterTable *locals = NULL; + static QRegister *current = NULL; + static QRegisterStack stack; - static QRegisterStack stack; + static inline void + undo_edit(void) + { + current->dot = interface.ssm(SCI_GETCURRENTPOS); + undo.push_var(current)->undo_edit(); + } } static QRegister *register_argument = NULL; @@ -148,57 +154,16 @@ QRegister::undo_edit(void) void QRegister::execute(bool locals) throw (State::Error) { - GotoTable *parent_goto_table = Goto::table; - GotoTable macro_goto_table; - - QRegisterTable *parent_locals = QRegisters::locals; - - State *parent_state = States::current; - gint parent_pc = macro_pc; - gchar *str; - - /* - * need this to fixup state on rubout: state machine emits undo token - * resetting state to parent's one, but the macro executed also emitted - * undo tokens resetting the state to StateStart - */ - undo.push_var(States::current); - States::current = &States::start; - - macro_pc = 0; - str = get_string(); - - Goto::table = ¯o_goto_table; - if (locals) { - QRegisters::locals = new QRegisterTable(); - QRegisters::locals->initialize(); - } + gchar *str = get_string(); try { - macro_execute(str); - if (Goto::skip_label) - throw State::Error("Label \"%s\" not found", - Goto::skip_label); + Execute::macro(str, locals); } catch (...) { g_free(str); - macro_pc = parent_pc; - States::current = parent_state; - Goto::table = parent_goto_table; - if (locals) - delete QRegisters::locals; - QRegisters::locals = parent_locals; - g_free(Goto::skip_label); - Goto::skip_label = NULL; throw; /* forward */ } g_free(str); - macro_pc = parent_pc; - States::current = parent_state; - Goto::table = parent_goto_table; - if (locals) - delete QRegisters::locals; - QRegisters::locals = parent_locals; } bool @@ -456,16 +456,6 @@ namespace States { namespace QRegisters { extern QRegisterTable globals; extern QRegisterTable *locals; - extern QRegister *current; - - inline void - undo_edit(void) - { - current->dot = interface.ssm(SCI_GETCURRENTPOS); - - undo.push_var<QRegister*>(current); - current->undo_edit(); - } enum Hook { HOOK_ADD = 1, |