From 82f2d9740a8d47af53c389d8f6edb10a6769801e Mon Sep 17 00:00:00 2001 From: Ben Kurtovic Date: Mon, 27 Apr 2015 14:43:14 -0500 Subject: [PATCH] Implement parse_bytes(), bugfixes, improve error messages. --- src/assembler/errors.c | 2 +- src/assembler/parse_util.c | 36 ++++++++++++++++++++++++++++++++++-- src/assembler/tokenizer.c | 32 +++++++++++++++++++------------- 3 files changed, 54 insertions(+), 16 deletions(-) diff --git a/src/assembler/errors.c b/src/assembler/errors.c index 6d9da59..083c7d9 100644 --- a/src/assembler/errors.c +++ b/src/assembler/errors.c @@ -35,7 +35,7 @@ static const char *error_descs[] = { [ED_LYT_BLOCK0] = "block zero cannot be mapped into a nonzero slot", [ED_LYT_SLOTS] = "multiple slot declarations for block directive", [ED_LYT_BLOCK_CROSS] = "instruction or data extends past block boundary", - [ED_LYT_OVERLAP] = "location overlaps with instruction or data", + [ED_LYT_OVERLAP] = "multiple instructions/data occupy same location", [ED_LYT_OVERLAP_HEAD] = "location overlaps with ROM header", [ED_SYM_DUPE_LABELS] = "duplicate definitions for label", diff --git a/src/assembler/parse_util.c b/src/assembler/parse_util.c index 9e61411..38dbc79 100644 --- a/src/assembler/parse_util.c +++ b/src/assembler/parse_util.c @@ -7,6 +7,7 @@ #include "parse_util.h" #include "directives.h" +#include "../logging.h" #include "../util.h" #define MAX_REGION_SIZE 32 @@ -125,6 +126,8 @@ bool parse_string(char **result, size_t *length, const char *arg, ssize_t size) *length = size - 2; *result = malloc(sizeof(char) * (*length)); + if (!*result) + OUT_OF_MEMORY() memcpy(*result, arg + 1, *length); return true; } @@ -137,8 +140,37 @@ bool parse_string(char **result, size_t *length, const char *arg, ssize_t size) */ bool parse_bytes(uint8_t **result, size_t *length, const char *arg, ssize_t size) { - // TODO - return false; + if (size <= 0) + return false; + + const char *end = arg + size; + uint8_t *bytes = NULL; + size_t nbytes = 0; + + while (arg != end) { + const char *start = arg; + while (arg != end && *arg != ' ') + arg++; + + uint32_t temp; + if (!parse_uint32_t(&temp, start, arg - start) || temp > UINT8_MAX) { + free(bytes); + return false; + } + + nbytes++; + bytes = realloc(bytes, sizeof(uint8_t) * nbytes); + if (!bytes) + OUT_OF_MEMORY() + bytes[nbytes - 1] = temp; + + if (arg++ == end) + break; + } + + *result = bytes; + *length = nbytes; + return true; } /* diff --git a/src/assembler/tokenizer.c b/src/assembler/tokenizer.c index a3bf20e..71a7a49 100644 --- a/src/assembler/tokenizer.c +++ b/src/assembler/tokenizer.c @@ -16,6 +16,7 @@ typedef struct { size_t size; const ASMLine **overlap_table; + const ASMLine **overlap_origins; const ASMLine *origin; uint8_t bank; bool cross_blocks; @@ -125,15 +126,12 @@ static ErrorInfo* handle_block_directive( if (bank >= MMU_NUM_ROM_BANKS || slot >= MMU_NUM_SLOTS) return error_info_create(line, ET_PREPROC, ED_PP_ARG_RANGE); - - if (nargs == 2) { - if (bank == 0 && slot != 0) - return error_info_create(line, ET_LAYOUT, ED_LYT_BLOCK0); - if (si->slots[bank] >= 0 && si->slots[bank] != slot) { - ErrorInfo *ei = error_info_create(line, ET_LAYOUT, ED_LYT_SLOTS); - error_info_append(ei, si->lines[bank]); - return ei; - } + if (bank == 0 && slot != 0) + return error_info_create(line, ET_LAYOUT, ED_LYT_BLOCK0); + if (si->slots[bank] >= 0 && si->slots[bank] != slot) { + ErrorInfo *ei = error_info_create(line, ET_LAYOUT, ED_LYT_SLOTS); + error_info_append(ei, si->lines[bank]); + return ei; } *offset = bank * MMU_ROM_BANK_SIZE; @@ -212,13 +210,14 @@ static ErrorInfo* parse_instruction( static ErrorInfo* check_layout( ASMLayoutInfo *li, const ASMLocation *loc, const ASMLine *line) { - const ASMLine *clash = NULL; + const ASMLine *clash = NULL, *clash_origin; if (loc->offset + loc->length > li->size) { clash = &bounds_sentinel; } else { for (size_t i = 0; i < loc->length; i++) { if (li->overlap_table[loc->offset + i]) { clash = li->overlap_table[loc->offset + i]; + clash_origin = li->overlap_origins[loc->offset + i]; break; } } @@ -231,8 +230,11 @@ static ErrorInfo* check_layout( if (li->origin) error_info_append(ei, li->origin); - if (clash != &header_sentinel && clash != &bounds_sentinel) + if (clash != &header_sentinel && clash != &bounds_sentinel) { error_info_append(ei, clash); + if (clash_origin) + error_info_append(ei, clash_origin); + } return ei; } @@ -244,8 +246,10 @@ static ErrorInfo* check_layout( return ei; } - for (size_t i = 0; i < loc->length; i++) + for (size_t i = 0; i < loc->length; i++) { li->overlap_table[loc->offset + i] = line; + li->overlap_origins[loc->offset + i] = li->origin; + } return NULL; } @@ -263,7 +267,8 @@ ErrorInfo* tokenize(AssemblerState *state) .origin = NULL, .bank = 0, .cross_blocks = state->cross_blocks }; li.overlap_table = calloc(li.size, sizeof(const ASMLine*)); - if (!li.overlap_table) + li.overlap_origins = calloc(li.size, sizeof(const ASMLine*)); + if (!li.overlap_table || !li.overlap_origins) OUT_OF_MEMORY() ErrorInfo *ei = NULL; @@ -332,5 +337,6 @@ ErrorInfo* tokenize(AssemblerState *state) state->instructions = dummy_inst.next; state->data = dummy_data.next; free(li.overlap_table); + free(li.overlap_origins); return ei; }