aboutsummaryrefslogtreecommitdiff
path: root/src/emitc.c
diff options
context:
space:
mode:
authorFranklin Wei <git@fwei.tk>2015-11-21 18:27:38 -0500
committerFranklin Wei <git@fwei.tk>2015-11-21 18:27:38 -0500
commitafc3e4b88e193025e49736e545ccb7765b19d1b5 (patch)
treeefb32f2b86739e38c466ee514f2cb6338fa99fe7 /src/emitc.c
parent03a7066353fad59b7c29b57baa94f84bcc5cfcda (diff)
downloadducky-afc3e4b88e193025e49736e545ccb7765b19d1b5.zip
ducky-afc3e4b88e193025e49736e545ccb7765b19d1b5.tar.gz
ducky-afc3e4b88e193025e49736e545ccb7765b19d1b5.tar.bz2
ducky-afc3e4b88e193025e49736e545ccb7765b19d1b5.tar.xz
better error handling
Diffstat (limited to 'src/emitc.c')
-rw-r--r--src/emitc.c79
1 files changed, 45 insertions, 34 deletions
diff --git a/src/emitc.c b/src/emitc.c
index bf79a47..e200ce5 100644
--- a/src/emitc.c
+++ b/src/emitc.c
@@ -13,14 +13,15 @@ struct var_t {
bool constant;
};
-int file_des, out_fd;
-unsigned current_line, num_lines;
+static int file_des, out_fd;
+static unsigned current_line, num_lines;
-off_t *line_offset;
+static off_t *line_offset;
-bool want_quit;
-int repeats_left;
-imm_t repeat_line;
+static bool want_quit;
+static int repeats_left;
+static imm_t repeat_line;
+static jmp_buf exit_point;
static void error(const char *fmt, ...) __attribute__((noreturn,format(print,1,2)));
static void vid_write(const char *str);
@@ -138,7 +139,7 @@ static void __attribute__((noreturn,format(printf,1,2))) error(const char *fmt,
vid_writef("ERROR: %s\n", fmtbuf);
va_end(ap);
- exit(EXIT_FAILURE);
+ longjmp(exit_point, 1);
}
static void __attribute__((format(printf,1,2))) warning(const char *fmt, ...)
@@ -762,22 +763,8 @@ static void (*instr_tab[0x100])(void) = {
inc_line_pointer, /* 0xff */
};
-void ducky_to_c(int fd, int out)
+void write_stub_code(int num_lines)
{
- file_des = fd;
- out_fd = out;
-
- init_globals();
-
- if(read_imm() != DUCKY_MAGIC)
- error("unknown format");
-
- num_lines = read_imm();
- for(unsigned int i = 1; i <= num_lines; ++i)
- {
- read_imm();
- }
-
write_src("/* generated by ducky */\n\n");
write_src("#include <stdarg.h>\n");
@@ -875,7 +862,6 @@ void ducky_to_c(int fd, int out)
write_src("{\n");
write_src("/* this uses labels as values, a GCC extension */\n");
-
write_src("const void *jump_table[%d] = ", num_lines + 1);
write_src("{\n");
write_src("NULL,\n");
@@ -885,18 +871,43 @@ void ducky_to_c(int fd, int out)
}
write_src("};\n");
write_src_noindent("\n");
+}
- /* and... compile! */
- while(!want_quit)
+int ducky_to_c(int fd, int out)
+{
+ if(!setjmp(exit_point))
{
- instr_t instr = read_instr();
- if(want_quit)
- break;
- void (*handler)(void) = instr_tab[instr];
- if(handler)
- handler();
- else
- error("invalid instruction %d", instr);
+ file_des = fd;
+ out_fd = out;
+
+ init_globals();
+
+ if(read_imm() != DUCKY_MAGIC)
+ error("unknown format");
+
+ num_lines = read_imm();
+ for(unsigned int i = 1; i <= num_lines; ++i)
+ {
+ read_imm();
+ }
+
+ write_stub_code(num_lines);
+
+ /* and... compile! */
+ while(!want_quit)
+ {
+ instr_t instr = read_instr();
+ if(want_quit)
+ break;
+ void (*handler)(void) = instr_tab[instr];
+ if(handler)
+ handler();
+ else
+ error("invalid instruction %d", instr);
+ }
+ write_src("}\n");
+ return 0;
}
- write_src("}\n");
+ else
+ return 1;
}