diff options
author | Robin Haberkorn <robin.haberkorn@googlemail.com> | 2013-05-30 01:46:41 +0200 |
---|---|---|
committer | Robin Haberkorn <robin.haberkorn@googlemail.com> | 2014-02-15 15:21:53 +0100 |
commit | 78ad52e40992d6e68238dc1574d4ae6c6f922d27 (patch) | |
tree | a254003b43ac62957a1cc0a1f8275e527240a135 | |
parent | 1f8d558597098f78aeba4ed5f70824f98dc60060 (diff) | |
download | sciteco-78ad52e40992d6e68238dc1574d4ae6c6f922d27.tar.gz |
fixed Execute::macro() and Execute::file() exceptions
* might throw other exceptions that must be associated with the parent macro level's (stack frame)
* add position information to "label not found" errors
* Error copy constructors
-rw-r--r-- | src/parser.cpp | 33 | ||||
-rw-r--r-- | src/parser.h | 44 |
2 files changed, 69 insertions, 8 deletions
diff --git a/src/parser.cpp b/src/parser.cpp index 67d8b73..4dbec88 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -72,6 +72,10 @@ static gint nest_level = 0; gchar *strings[2] = {NULL, NULL}; gchar escape_char = '\x1B'; +/* + * handles all expected exceptions, converting them to + * State::Error and preparing them for stack frame insertion + */ void Execute::step(const gchar *macro, gint stop_pos) throw (State::Error, ReplaceCmdline) @@ -104,9 +108,12 @@ Execute::step(const gchar *macro, gint stop_pos) } } +/* + * may throw non State::Error exceptions which are not to be + * associated with the macro invocation stack frame + */ void Execute::macro(const gchar *macro, bool locals) - throw (State::Error, ReplaceCmdline) { GotoTable *parent_goto_table = Goto::table; GotoTable macro_goto_table(false); @@ -125,6 +132,7 @@ Execute::macro(const gchar *macro, bool locals) macro_pc = 0; Goto::table = ¯o_goto_table; + /* locals are allocated so that we do not waste call stack space */ if (locals) { parent_locals = QRegisters::locals; QRegisters::locals = new QRegisterTable(false); @@ -132,9 +140,14 @@ Execute::macro(const gchar *macro, bool locals) try { step(macro, strlen(macro)); - if (Goto::skip_label) - throw State::Error("Label \"%s\" not found", + if (Goto::skip_label) { + State::Error error("Label \"%s\" not found", Goto::skip_label); + error.pos = strlen(macro); + String::get_coord(macro, error.pos, + error.line, error.column); + throw error; + } } catch (...) { g_free(Goto::skip_label); Goto::skip_label = NULL; @@ -163,7 +176,6 @@ Execute::macro(const gchar *macro, bool locals) void Execute::file(const gchar *filename, bool locals) - throw (State::Error, ReplaceCmdline) { gchar *macro_str, *p; @@ -212,6 +224,19 @@ State::Error::Error(const gchar *fmt, ...) va_end(ap); } +State::Error::Error(const Error &inst) + : description(g_strdup(inst.description)), + pos(inst.pos), line(inst.line), column(inst.column) +{ + /* shallow copy of the frames */ + frames = g_slist_copy(inst.frames); + + for (GSList *cur = frames; cur; cur = g_slist_next(cur)) { + Frame *frame = (Frame *)cur->data; + cur->data = frame->copy(); + } +} + void State::Error::add_frame(Frame *frame) { diff --git a/src/parser.h b/src/parser.h index 76cd7c7..f7c9bed 100644 --- a/src/parser.h +++ b/src/parser.h @@ -51,6 +51,7 @@ public: gint pos; gint line, column; + virtual Frame *copy() const = 0; virtual ~Frame() {} virtual void display(gint nr) = 0; @@ -63,6 +64,18 @@ public: QRegFrame(const gchar *_name) : name(g_strdup(_name)) {} + Frame * + copy() const + { + Frame *frame = new QRegFrame(name); + + frame->pos = pos; + frame->line = line; + frame->column = column; + + return frame; + } + ~QRegFrame() { g_free(name); @@ -84,6 +97,18 @@ public: FileFrame(const gchar *_name) : name(g_strdup(_name)) {} + Frame * + copy() const + { + Frame *frame = new FileFrame(name); + + frame->pos = pos; + frame->line = line; + frame->column = column; + + return frame; + } + ~FileFrame() { g_free(name); @@ -100,6 +125,18 @@ public: class ToplevelFrame : public Frame { public: + Frame * + copy() const + { + Frame *frame = new ToplevelFrame; + + frame->pos = pos; + frame->line = line; + frame->column = column; + + return frame; + } + void display(gint nr) { @@ -110,6 +147,7 @@ public: }; Error(const gchar *fmt, ...) G_GNUC_PRINTF(2, 3); + Error(const Error &inst); ~Error(); void add_frame(Frame *frame); @@ -407,10 +445,8 @@ extern gchar escape_char; namespace Execute { void step(const gchar *macro, gint stop_pos) throw (State::Error, ReplaceCmdline); - void macro(const gchar *macro, bool locals = true) - throw (State::Error, ReplaceCmdline); - void file(const gchar *filename, bool locals = true) - throw (State::Error, ReplaceCmdline); + void macro(const gchar *macro, bool locals = true); + void file(const gchar *filename, bool locals = true); } #endif |