diff options
| author | Franklin Wei <git@fwei.tk> | 2015-11-21 18:27:38 -0500 |
|---|---|---|
| committer | Franklin Wei <git@fwei.tk> | 2015-11-21 18:27:38 -0500 |
| commit | afc3e4b88e193025e49736e545ccb7765b19d1b5 (patch) | |
| tree | efb32f2b86739e38c466ee514f2cb6338fa99fe7 /src/compile.c | |
| parent | 03a7066353fad59b7c29b57baa94f84bcc5cfcda (diff) | |
| download | ducky-afc3e4b88e193025e49736e545ccb7765b19d1b5.zip ducky-afc3e4b88e193025e49736e545ccb7765b19d1b5.tar.gz ducky-afc3e4b88e193025e49736e545ccb7765b19d1b5.tar.bz2 ducky-afc3e4b88e193025e49736e545ccb7765b19d1b5.tar.xz | |
better error handling
Diffstat (limited to 'src/compile.c')
| -rw-r--r-- | src/compile.c | 205 |
1 files changed, 106 insertions, 99 deletions
diff --git a/src/compile.c b/src/compile.c index 58abdeb..29cb91d 100644 --- a/src/compile.c +++ b/src/compile.c @@ -35,6 +35,8 @@ static unsigned lines_executed = 0, current_line = 0, num_lines; static int file_des = -1, out_fd = -1; +static jmp_buf exit_point; + struct var_t { char name[VARNAME_MAX]; bool constant; @@ -169,10 +171,10 @@ static void __attribute__((noreturn,format(printf,1,2))) error(const char *fmt, vsnprintf(fmtbuf, sizeof(fmtbuf), fmt, ap); if(current_line) vid_logf("Line %d: ", current_line); - vid_logf("ERROR: %s\n", fmtbuf); + vid_logf("ERROR: %s", fmtbuf); va_end(ap); - exit(EXIT_FAILURE); + longjmp(exit_point, 1); } static void __attribute__((format(printf,1,2))) warning(const char *fmt, ...) @@ -1616,128 +1618,133 @@ static void init_globals(void) bytes_written = 0; } -void ducky_compile(int fd, bool verbose, int out) +int ducky_compile(int fd, bool verbose, int out) { - init_globals(); - - if(verbose) + if(!setjmp(exit_point)) { - vid_logf("COMPILER INIT"); - } + init_globals(); - file_des = fd; - out_fd = out; + if(verbose) + { + vid_logf("COMPILER INIT"); + } - atexit(exit_handler); + file_des = fd; + out_fd = out; - if(file_des < 0) - error("invalid file"); + atexit(exit_handler); - init_optable(); - init_tokmap(); + if(file_des < 0) + error("invalid file"); - line_offset = index_lines(file_des, &num_lines); - write_imm(DUCKY_MAGIC); - write_imm(num_lines); - off_t linetab_off = bytes_written; - for(unsigned i = 1; i <= num_lines; ++i) - { - write_imm(0); - } - if(verbose) - { - vid_logf("Indexing complete (%u lines).", num_lines); - vid_logf("Compiling..."); - } + init_optable(); + init_tokmap(); + + line_offset = index_lines(file_des, &num_lines); + write_imm(DUCKY_MAGIC); + write_imm(num_lines); + off_t linetab_off = bytes_written; + for(unsigned i = 1; i <= num_lines; ++i) + { + write_imm(0); + } + if(verbose) + { + vid_logf("Indexing complete (%u lines).", num_lines); + vid_logf("Compiling..."); + } - /* initialize some other constants */ + /* initialize some other constants */ - makeConstantVariable(".", 0); + makeConstantVariable(".", 0); - makeConstantVariable("true", 1); - makeConstantVariable("false", 0); + makeConstantVariable("true", 1); + makeConstantVariable("false", 0); - /* initialize labels (using output from index_lines) */ - index_labels(file_des); + /* initialize labels (using output from index_lines) */ + index_labels(file_des); - int repeats_left = 0; - off_t code_start = bytes_written; + int repeats_left = 0; + off_t code_start = bytes_written; - while(1) - { - char instr_buf[MAX_LINE_LEN]; - memset(instr_buf, 0, sizeof(instr_buf)); - if(read_line(file_des, instr_buf, sizeof(instr_buf)) <= 0) + while(1) { - if(verbose) - vid_logf("end of file"); - goto done; - } - char *tok = NULL, *save = NULL; + char instr_buf[MAX_LINE_LEN]; + memset(instr_buf, 0, sizeof(instr_buf)); + if(read_line(file_des, instr_buf, sizeof(instr_buf)) <= 0) + { + if(verbose) + vid_logf("end of file"); + goto done; + } + char *tok = NULL, *save = NULL; - ++current_line; - write_instr(LINEMARK); + ++current_line; + write_instr(LINEMARK); - char *buf = instr_buf; + char *buf = instr_buf; - line_offset[current_line] = bytes_written; + line_offset[current_line] = bytes_written; - /* compile all the commands on this line/instruction */ - do { - tok = strtok_r(buf, " -\t", &save); - buf = NULL; + /* compile all the commands on this line/instruction */ + do { + tok = strtok_r(buf, " -\t", &save); + buf = NULL; - if(!tok) - break; + if(!tok) + break; - int hash = tok_hash(tok) % TOKMAP_SIZE; - struct token_t *t = tokmap+hash; - if(hash >= 0 && strcmp(t->tok, tok) == 0) - switch(tokmap[hash].func(&save)) + int hash = tok_hash(tok) % TOKMAP_SIZE; + struct token_t *t = tokmap+hash; + if(hash >= 0 && strcmp(t->tok, tok) == 0) + switch(tokmap[hash].func(&save)) + { + case OK: + break; + case BREAK: + goto break_out; + case DONE: + goto done; + case NEXT: + goto next_line; + default: + error("FIXME: invalid return value"); + } +#ifdef DUCKY_ROCKBOX + else if(strlen(tok) == 1) { - case OK: - break; - case BREAK: - goto break_out; - case DONE: - goto done; - case NEXT: - goto next_line; - default: - error("FIXME: invalid return value"); + write_instr(ADD_CHAR); + write_byte(tok[0]); } -#ifdef DUCKY_ROCKBOX - else if(strlen(tok) == 1) - { - write_instr(ADD_CHAR); - write_byte(tok[0]); - } #endif - else if(tok[0] == '#') - goto next_line; - else - { - error("unknown token `%s` on line %d %d", tok, current_line); - goto done; - } - } while(tok); - break_out: - ; - next_line: - ; - } + else if(tok[0] == '#') + goto next_line; + else + { + error("unknown token `%s` on line %d %d", tok, current_line); + goto done; + } + } while(tok); + break_out: + ; + next_line: + ; + } -done: + done: - /* add a final instruction to flush the key buffer */ - write_instr(LINEMARK); + /* add a final instruction to flush the key buffer */ + write_instr(LINEMARK); - /* go back and fill in the offset table */ - lseek(out_fd, linetab_off, SEEK_SET); - for(unsigned i = 1; i <= num_lines; ++i) - { - write_imm(line_offset[i]); - } + /* go back and fill in the offset table */ + lseek(out_fd, linetab_off, SEEK_SET); + for(unsigned i = 1; i <= num_lines; ++i) + { + write_imm(line_offset[i]); + } - return; + return 0; + } + else + return 1; } |