aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorRobin Haberkorn <robin.haberkorn@googlemail.com>2012-11-20 01:57:14 +0100
committerRobin Haberkorn <robin.haberkorn@googlemail.com>2012-11-20 06:07:34 +0100
commitdf9f83a249e59867373e06c79aa8f57a5c9640b7 (patch)
tree1a105e4c80877b58f3b0e5dfbe418910144f1077
parentec510eda5f080d39906c396a36cba89188031640 (diff)
downloadsciteco-df9f83a249e59867373e06c79aa8f57a5c9640b7.tar.gz
cleanup macro execution functions: common namespace, Execute::file() uses Execute::macro()
-rw-r--r--cmdline.cpp2
-rw-r--r--main.cpp9
-rw-r--r--parser.cpp89
-rw-r--r--parser.h11
-rw-r--r--qbuffers.cpp59
-rw-r--r--qbuffers.h10
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)
diff --git a/main.cpp b/main.cpp
index 312064f..05324d3 100644
--- a/main.cpp
+++ b/main.cpp
@@ -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);
diff --git a/parser.cpp b/parser.cpp
index e7ff980..fb31add 100644
--- a/parser.cpp
+++ b/parser.cpp
@@ -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 = &macro_goto_table;
if (locals) {
- QRegisters::locals = new QRegisterTable();
- QRegisters::locals->initialize();
+ parent_locals = QRegisters::locals;
+ macro_locals.initialize();
+ QRegisters::locals = &macro_locals;
}
- if (!g_file_get_contents(filename, &macro, 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, &macro_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;
}
diff --git a/parser.h b/parser.h
index 2451a58..819e418 100644
--- a/parser.h
+++ b/parser.h
@@ -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 = &macro_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
diff --git a/qbuffers.h b/qbuffers.h
index df05c08..3613c93 100644
--- a/qbuffers.h
+++ b/qbuffers.h
@@ -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,