| @@ -201,10 +201,7 @@ size_t assemble(const LineBuffer *source, uint8_t **binary_ptr, ErrorInfo **ei_p | |||||
| if ((error_info = resolve_symbols(&state))) | if ((error_info = resolve_symbols(&state))) | ||||
| goto error; | goto error; | ||||
| uint8_t *binary = malloc(sizeof(uint8_t) * state.rom_size); | |||||
| if (!binary) | |||||
| OUT_OF_MEMORY() | |||||
| uint8_t *binary = cr_malloc(sizeof(uint8_t) * state.rom_size); | |||||
| serialize_binary(&state, binary); | serialize_binary(&state, binary); | ||||
| *binary_ptr = binary; | *binary_ptr = binary; | ||||
| retval = state.rom_size; | retval = state.rom_size; | ||||
| @@ -6,7 +6,7 @@ | |||||
| #include "errors.h" | #include "errors.h" | ||||
| #include "state.h" | #include "state.h" | ||||
| #include "../assembler.h" | #include "../assembler.h" | ||||
| #include "../logging.h" | |||||
| #include "../util.h" | |||||
| /* Error strings */ | /* Error strings */ | ||||
| @@ -82,27 +82,20 @@ struct ErrorInfo { | |||||
| */ | */ | ||||
| static ASMErrorLine* create_error_line(const ASMLine *line) | static ASMErrorLine* create_error_line(const ASMLine *line) | ||||
| { | { | ||||
| ASMErrorLine *el = malloc(sizeof(ASMErrorLine)); | |||||
| if (!el) | |||||
| OUT_OF_MEMORY() | |||||
| ASMErrorLine *el = cr_malloc(sizeof(ASMErrorLine)); | |||||
| const char *source = line->original->data; | const char *source = line->original->data; | ||||
| size_t length = line->original->length; | size_t length = line->original->length; | ||||
| if (!(el->data = malloc(sizeof(char) * length))) | |||||
| OUT_OF_MEMORY() | |||||
| // Ignore spaces at beginning: | // Ignore spaces at beginning: | ||||
| while (length > 0 && (*source == ' ' || *source == '\t')) | while (length > 0 && (*source == ' ' || *source == '\t')) | ||||
| source++, length--; | source++, length--; | ||||
| el->data = cr_malloc(sizeof(char) * length); | |||||
| memcpy(el->data, source, length); | memcpy(el->data, source, length); | ||||
| el->length = length; | el->length = length; | ||||
| el->lineno = line->original->lineno; | el->lineno = line->original->lineno; | ||||
| el->filename = strdup(line->filename); | |||||
| if (!el->filename) | |||||
| OUT_OF_MEMORY() | |||||
| el->filename = cr_strdup(line->filename); | |||||
| el->next = NULL; | el->next = NULL; | ||||
| return el; | return el; | ||||
| } | } | ||||
| @@ -119,10 +112,7 @@ static ASMErrorLine* create_error_line(const ASMLine *line) | |||||
| ErrorInfo* error_info_create( | ErrorInfo* error_info_create( | ||||
| const ASMLine *line, ASMErrorType err_type, ASMErrorDesc err_desc) | const ASMLine *line, ASMErrorType err_type, ASMErrorDesc err_desc) | ||||
| { | { | ||||
| ErrorInfo *einfo = malloc(sizeof(ErrorInfo)); | |||||
| if (!einfo) | |||||
| OUT_OF_MEMORY() | |||||
| ErrorInfo *einfo = cr_malloc(sizeof(ErrorInfo)); | |||||
| einfo->type = err_type; | einfo->type = err_type; | ||||
| einfo->desc = err_desc; | einfo->desc = err_desc; | ||||
| einfo->line = line ? create_error_line(line) : NULL; | einfo->line = line ? create_error_line(line) : NULL; | ||||
| @@ -5,7 +5,7 @@ | |||||
| #include <string.h> | #include <string.h> | ||||
| #include "hash_table.h" | #include "hash_table.h" | ||||
| #include "../logging.h" | |||||
| #include "../util.h" | |||||
| #define INITIAL_BUCKETS 127 | #define INITIAL_BUCKETS 127 | ||||
| @@ -61,13 +61,8 @@ static inline bool keyeq(const char *s1, const char *s2, ssize_t size) | |||||
| HashTable* hash_table_new( | HashTable* hash_table_new( | ||||
| size_t key_offset, size_t next_offset, HashFreeCallback callback) | size_t key_offset, size_t next_offset, HashFreeCallback callback) | ||||
| { | { | ||||
| HashTable *table; | |||||
| if (!(table = malloc(sizeof(HashTable)))) | |||||
| OUT_OF_MEMORY() | |||||
| if (!(table->nodes = calloc(INITIAL_BUCKETS, sizeof(HashNode*)))) | |||||
| OUT_OF_MEMORY() | |||||
| HashTable *table = cr_malloc(sizeof(HashTable)); | |||||
| table->nodes = cr_calloc(INITIAL_BUCKETS, sizeof(HashNode*)); | |||||
| table->buckets = INITIAL_BUCKETS; | table->buckets = INITIAL_BUCKETS; | ||||
| table->key_offset = key_offset; | table->key_offset = key_offset; | ||||
| table->next_offset = next_offset; | table->next_offset = next_offset; | ||||
| @@ -7,7 +7,7 @@ | |||||
| #include "instructions.h" | #include "instructions.h" | ||||
| #include "inst_args.h" | #include "inst_args.h" | ||||
| #include "parse_util.h" | #include "parse_util.h" | ||||
| #include "../logging.h" | |||||
| #include "../util.h" | |||||
| /* Helper macros for get_inst_parser() */ | /* Helper macros for get_inst_parser() */ | ||||
| @@ -26,8 +26,7 @@ | |||||
| #define INST_ALLOC_(len) \ | #define INST_ALLOC_(len) \ | ||||
| *length = len; \ | *length = len; \ | ||||
| if (!(*bytes = malloc(sizeof(uint8_t) * (len)))) \ | |||||
| OUT_OF_MEMORY() | |||||
| *bytes = cr_malloc(sizeof(uint8_t) * (len)); | |||||
| #define INST_SET_(b, val) ((*bytes)[b] = val) | #define INST_SET_(b, val) ((*bytes)[b] = val) | ||||
| #define INST_SET1_(b1) INST_SET_(0, b1) | #define INST_SET1_(b1) INST_SET_(0, b1) | ||||
| @@ -55,7 +54,7 @@ static ASMErrorDesc parse_inst_##mnemonic( \ | |||||
| #define INST_TAKES_NO_ARGS \ | #define INST_TAKES_NO_ARGS \ | ||||
| if (ap_info.arg) \ | if (ap_info.arg) \ | ||||
| INST_ERROR(TOO_MANY_ARGS) \ | |||||
| INST_ERROR(TOO_MANY_ARGS) | |||||
| #define INST_TAKES_ARGS(lo, hi) \ | #define INST_TAKES_ARGS(lo, hi) \ | ||||
| if (!ap_info.arg) \ | if (!ap_info.arg) \ | ||||
| @@ -104,9 +103,7 @@ static ASMErrorDesc parse_inst_##mnemonic( \ | |||||
| } | } | ||||
| #define INST_RETURN_WITH_SYMBOL(len, label, ...) { \ | #define INST_RETURN_WITH_SYMBOL(len, label, ...) { \ | ||||
| *symbol = strdup(label); \ | |||||
| if (!(*symbol)) \ | |||||
| OUT_OF_MEMORY() \ | |||||
| *symbol = cr_strdup(label); \ | |||||
| INST_ALLOC_(len) \ | INST_ALLOC_(len) \ | ||||
| INST_FILL_BYTES_(len - 2, __VA_ARGS__) \ | INST_FILL_BYTES_(len - 2, __VA_ARGS__) \ | ||||
| return ED_NONE; \ | return ED_NONE; \ | ||||
| @@ -9,6 +9,7 @@ | |||||
| #include "io.h" | #include "io.h" | ||||
| #include "../logging.h" | #include "../logging.h" | ||||
| #include "../util.h" | |||||
| /* | /* | ||||
| Deallocate a LineBuffer previously created with read_source_file(). | Deallocate a LineBuffer previously created with read_source_file(). | ||||
| @@ -59,14 +60,9 @@ LineBuffer* read_source_file(const char *path, bool print_errors) | |||||
| return NULL; | return NULL; | ||||
| } | } | ||||
| LineBuffer *source = malloc(sizeof(LineBuffer)); | |||||
| if (!source) | |||||
| OUT_OF_MEMORY() | |||||
| LineBuffer *source = cr_malloc(sizeof(LineBuffer)); | |||||
| source->lines = NULL; | source->lines = NULL; | ||||
| source->filename = strdup(path); | |||||
| if (!source->filename) | |||||
| OUT_OF_MEMORY() | |||||
| source->filename = cr_strdup(path); | |||||
| Line dummy = {.next = NULL}; | Line dummy = {.next = NULL}; | ||||
| Line *line, *prev = &dummy; | Line *line, *prev = &dummy; | ||||
| @@ -90,10 +86,7 @@ LineBuffer* read_source_file(const char *path, bool print_errors) | |||||
| return NULL; | return NULL; | ||||
| } | } | ||||
| line = malloc(sizeof(Line)); | |||||
| if (!line) | |||||
| OUT_OF_MEMORY() | |||||
| line = cr_malloc(sizeof(Line)); | |||||
| line->data = data; | line->data = data; | ||||
| line->length = feof(fp) ? len : (len - 1); | line->length = feof(fp) ? len : (len - 1); | ||||
| line->lineno = lineno++; | line->lineno = lineno++; | ||||
| @@ -7,7 +7,6 @@ | |||||
| #include "parse_util.h" | #include "parse_util.h" | ||||
| #include "directives.h" | #include "directives.h" | ||||
| #include "../logging.h" | |||||
| #include "../util.h" | #include "../util.h" | ||||
| #define MAX_REGION_SIZE 32 | #define MAX_REGION_SIZE 32 | ||||
| @@ -183,9 +182,7 @@ bool parse_string(char **result, size_t *length, const char *arg, ssize_t size) | |||||
| return false; | return false; | ||||
| *length = size - 2; | *length = size - 2; | ||||
| *result = malloc(sizeof(char) * (*length)); | |||||
| if (!*result) | |||||
| OUT_OF_MEMORY() | |||||
| *result = cr_malloc(sizeof(char) * (*length)); | |||||
| memcpy(*result, arg + 1, *length); | memcpy(*result, arg + 1, *length); | ||||
| return true; | return true; | ||||
| } | } | ||||
| @@ -217,9 +214,7 @@ bool parse_bytes(uint8_t **result, size_t *length, const char *arg, ssize_t size | |||||
| } | } | ||||
| nbytes++; | nbytes++; | ||||
| bytes = realloc(bytes, sizeof(uint8_t) * nbytes); | |||||
| if (!bytes) | |||||
| OUT_OF_MEMORY() | |||||
| bytes = cr_realloc(bytes, sizeof(uint8_t) * nbytes); | |||||
| bytes[nbytes - 1] = temp; | bytes[nbytes - 1] = temp; | ||||
| if (arg < end - 1 && *arg == ',' && *(arg + 1) == ' ') | if (arg < end - 1 && *arg == ',' && *(arg + 1) == ' ') | ||||
| @@ -121,14 +121,8 @@ static size_t read_labels( | |||||
| return 0; | return 0; | ||||
| } | } | ||||
| ASMLine *line = malloc(sizeof(ASMLine)); | |||||
| if (!line) | |||||
| OUT_OF_MEMORY() | |||||
| line->data = malloc(sizeof(char) * (i - start + 1)); | |||||
| if (!line->data) | |||||
| OUT_OF_MEMORY() | |||||
| ASMLine *line = cr_malloc(sizeof(ASMLine)); | |||||
| line->data = cr_malloc(sizeof(char) * (i - start + 1)); | |||||
| memcpy_lc(line->data, source + start, i - start + 1); | memcpy_lc(line->data, source + start, i - start + 1); | ||||
| line->length = i - start + 1; | line->length = i - start + 1; | ||||
| line->is_label = true; | line->is_label = true; | ||||
| @@ -160,10 +154,7 @@ static ASMLine* normalize_line(const char *source, size_t length) | |||||
| source += offset; | source += offset; | ||||
| length -= offset; | length -= offset; | ||||
| char *data = malloc(sizeof(char) * length); | |||||
| if (!data) | |||||
| OUT_OF_MEMORY() | |||||
| char *data = cr_malloc(sizeof(char) * length); | |||||
| size_t si, di, slashes = 0; | size_t si, di, slashes = 0; | ||||
| bool has_content = false, space_pending = false, in_string = false; | bool has_content = false, space_pending = false, in_string = false; | ||||
| for (si = di = 0; si < length; si++) { | for (si = di = 0; si < length; si++) { | ||||
| @@ -206,14 +197,8 @@ static ASMLine* normalize_line(const char *source, size_t length) | |||||
| return head; | return head; | ||||
| } | } | ||||
| ASMLine *line = malloc(sizeof(ASMLine)); | |||||
| if (!line) | |||||
| OUT_OF_MEMORY() | |||||
| data = realloc(data, sizeof(char) * di); | |||||
| if (!data) | |||||
| OUT_OF_MEMORY() | |||||
| ASMLine *line = cr_malloc(sizeof(ASMLine)); | |||||
| data = cr_realloc(data, sizeof(char) * di); | |||||
| line->data = data; | line->data = data; | ||||
| line->length = di; | line->length = di; | ||||
| line->is_label = false; | line->is_label = false; | ||||
| @@ -239,10 +224,7 @@ static char* read_include_path(const ASMLine *line) | |||||
| if (maxlen >= INT_MAX) // Allows us to safely downcast to int later | if (maxlen >= INT_MAX) // Allows us to safely downcast to int later | ||||
| return NULL; | return NULL; | ||||
| char *path = malloc(sizeof(char) * maxlen), *base, *dup; | |||||
| if (!path) | |||||
| OUT_OF_MEMORY() | |||||
| char *path = cr_malloc(sizeof(char) * maxlen), *base, *dup; | |||||
| if (!(i = DIRECTIVE_OFFSET(line, DIR_INCLUDE))) | if (!(i = DIRECTIVE_OFFSET(line, DIR_INCLUDE))) | ||||
| goto error; | goto error; | ||||
| if (line->length - i <= 3) // Not long enough to hold a non-zero argument | if (line->length - i <= 3) // Not long enough to hold a non-zero argument | ||||
| @@ -252,8 +234,7 @@ static char* read_include_path(const ASMLine *line) | |||||
| if (!parse_string(&base, &baselen, line->data + i, line->length - i)) | if (!parse_string(&base, &baselen, line->data + i, line->length - i)) | ||||
| goto error; | goto error; | ||||
| if (!(dup = strdup(line->filename))) | |||||
| OUT_OF_MEMORY() | |||||
| dup = cr_strdup(line->filename); | |||||
| // TODO: should normalize filenames in some way to prevent accidental dupes | // TODO: should normalize filenames in some way to prevent accidental dupes | ||||
| snprintf(path, maxlen, "%s/%.*s", dirname(dup), (int) baselen, base); | snprintf(path, maxlen, "%s/%.*s", dirname(dup), (int) baselen, base); | ||||
| @@ -330,10 +311,7 @@ static ErrorInfo* build_asm_lines( | |||||
| goto error; | goto error; | ||||
| } | } | ||||
| ASMInclude *include = malloc(sizeof(ASMInclude)); | |||||
| if (!include) | |||||
| OUT_OF_MEMORY() | |||||
| ASMInclude *include = cr_malloc(sizeof(ASMInclude)); | |||||
| include->lines = incbuffer; | include->lines = incbuffer; | ||||
| include->next = *includes; | include->next = *includes; | ||||
| *includes = include; | *includes = include; | ||||
| @@ -9,7 +9,6 @@ | |||||
| #include "instructions.h" | #include "instructions.h" | ||||
| #include "inst_args.h" | #include "inst_args.h" | ||||
| #include "parse_util.h" | #include "parse_util.h" | ||||
| #include "../logging.h" | |||||
| #include "../mmu.h" | #include "../mmu.h" | ||||
| #include "../rom.h" | #include "../rom.h" | ||||
| #include "../util.h" | #include "../util.h" | ||||
| @@ -63,12 +62,8 @@ static void init_layout_info(ASMLayoutInfo *li, AssemblerState *state) | |||||
| li->origin = NULL; | li->origin = NULL; | ||||
| li->bank = 0; | li->bank = 0; | ||||
| li->cross_blocks = state->cross_blocks; | li->cross_blocks = state->cross_blocks; | ||||
| if (!(li->overlap_table = calloc(li->size, sizeof(const ASMLine*)))) | |||||
| OUT_OF_MEMORY() | |||||
| if (!(li->overlap_origins = calloc(li->size, sizeof(const ASMLine*)))) | |||||
| OUT_OF_MEMORY() | |||||
| li->overlap_table = cr_calloc(li->size, sizeof(const ASMLine*)); | |||||
| li->overlap_origins = cr_calloc(li->size, sizeof(const ASMLine*)); | |||||
| for (size_t i = 0; i < HEADER_SIZE; i++) | for (size_t i = 0; i < HEADER_SIZE; i++) | ||||
| li->overlap_table[state->header.offset + i] = &header_sentinel; | li->overlap_table[state->header.offset + i] = &header_sentinel; | ||||
| @@ -104,10 +99,7 @@ static ErrorInfo* add_label_to_table( | |||||
| if (argparse_condition(&cond, info)) | if (argparse_condition(&cond, info)) | ||||
| return error_info_create(line, ET_SYMBOL, ED_SYM_IS_CONDITION); | return error_info_create(line, ET_SYMBOL, ED_SYM_IS_CONDITION); | ||||
| char *symbol = strndup(line->data, line->length - 1); | |||||
| if (!symbol) | |||||
| OUT_OF_MEMORY() | |||||
| char *symbol = cr_strndup(line->data, line->length - 1); | |||||
| const ASMSymbol *current = asm_symtable_find(symtable, symbol); | const ASMSymbol *current = asm_symtable_find(symtable, symbol); | ||||
| if (current) { | if (current) { | ||||
| ErrorInfo *ei = error_info_create(line, ET_SYMBOL, ED_SYM_DUPE_LABELS); | ErrorInfo *ei = error_info_create(line, ET_SYMBOL, ED_SYM_DUPE_LABELS); | ||||
| @@ -116,10 +108,7 @@ static ErrorInfo* add_label_to_table( | |||||
| return ei; | return ei; | ||||
| } | } | ||||
| ASMSymbol *label = malloc(sizeof(ASMSymbol)); | |||||
| if (!label) | |||||
| OUT_OF_MEMORY() | |||||
| ASMSymbol *label = cr_malloc(sizeof(ASMSymbol)); | |||||
| label->offset = map_into_slot(offset, | label->offset = map_into_slot(offset, | ||||
| (slot >= 0) ? slot : default_bank_slot(offset / MMU_ROM_BANK_SIZE)); | (slot >= 0) ? slot : default_bank_slot(offset / MMU_ROM_BANK_SIZE)); | ||||
| label->symbol = symbol; | label->symbol = symbol; | ||||
| @@ -169,13 +158,8 @@ static ErrorInfo* handle_define_directive( | |||||
| if (!argparse_immediate(&imm, info)) | if (!argparse_immediate(&imm, info)) | ||||
| return error_info_create(line, ET_PREPROC, ED_PP_BAD_ARG); | return error_info_create(line, ET_PREPROC, ED_PP_BAD_ARG); | ||||
| ASMDefine *define = malloc(sizeof(ASMDefine)); | |||||
| if (!define) | |||||
| OUT_OF_MEMORY() | |||||
| if (!(define->name = strndup(key, keylen))) | |||||
| OUT_OF_MEMORY() | |||||
| ASMDefine *define = cr_malloc(sizeof(ASMDefine)); | |||||
| define->name = cr_strndup(key, keylen); | |||||
| define->value = imm; | define->value = imm; | ||||
| define->line = line; | define->line = line; | ||||
| asm_deftable_insert(deftab, define); | asm_deftable_insert(deftab, define); | ||||
| @@ -285,9 +269,7 @@ static bool parse_space( | |||||
| } | } | ||||
| *length = bytes[0]; | *length = bytes[0]; | ||||
| if (!(*result = malloc(sizeof(uint8_t) * (*length)))) | |||||
| OUT_OF_MEMORY() | |||||
| *result = cr_malloc(sizeof(uint8_t) * (*length)); | |||||
| memset(*result, nbytes == 2 ? bytes[1] : 0, *length); | memset(*result, nbytes == 2 ? bytes[1] : 0, *length); | ||||
| free(bytes); | free(bytes); | ||||
| return true; | return true; | ||||
| @@ -328,10 +310,7 @@ static ErrorInfo* parse_data( | |||||
| const char *arg = line->data + dir_offset; | const char *arg = line->data + dir_offset; | ||||
| size_t arglen = line->length - dir_offset; | size_t arglen = line->length - dir_offset; | ||||
| ASMData *data = malloc(sizeof(ASMData)); | |||||
| if (!data) | |||||
| OUT_OF_MEMORY() | |||||
| ASMData *data = cr_malloc(sizeof(ASMData)); | |||||
| data->loc.offset = offset; | data->loc.offset = offset; | ||||
| data->next = NULL; | data->next = NULL; | ||||
| @@ -386,10 +365,7 @@ static ErrorInfo* parse_instruction( | |||||
| if (edesc != ED_NONE) | if (edesc != ED_NONE) | ||||
| return error_info_create(line, ET_PARSER, edesc); | return error_info_create(line, ET_PARSER, edesc); | ||||
| ASMInstruction *inst = malloc(sizeof(ASMInstruction)); | |||||
| if (!inst) | |||||
| OUT_OF_MEMORY() | |||||
| ASMInstruction *inst = cr_malloc(sizeof(ASMInstruction)); | |||||
| inst->loc.offset = offset; | inst->loc.offset = offset; | ||||
| inst->loc.length = length; | inst->loc.length = length; | ||||
| inst->bytes = bytes; | inst->bytes = bytes; | ||||
| @@ -10,6 +10,7 @@ | |||||
| #include "config.h" | #include "config.h" | ||||
| #include "logging.h" | #include "logging.h" | ||||
| #include "util.h" | |||||
| #include "version.h" | #include "version.h" | ||||
| /* | /* | ||||
| @@ -73,21 +74,15 @@ static int get_rom_paths(char ***path_ptr) | |||||
| dirp = opendir(ROMS_DIR); | dirp = opendir(ROMS_DIR); | ||||
| if (dirp) { | if (dirp) { | ||||
| paths = malloc(sizeof(char*) * psize); | |||||
| if (!paths) | |||||
| OUT_OF_MEMORY() | |||||
| paths = cr_malloc(sizeof(char*) * psize); | |||||
| while ((entry = readdir(dirp))) { | while ((entry = readdir(dirp))) { | ||||
| path = entry->d_name; | path = entry->d_name; | ||||
| if (ends_with(path, ".gg") || ends_with(path, ".bin")) { | if (ends_with(path, ".gg") || ends_with(path, ".bin")) { | ||||
| if (npaths >= psize) { | if (npaths >= psize) { | ||||
| paths = realloc(paths, sizeof(char*) * (psize *= 2)); | |||||
| if (!paths) | |||||
| OUT_OF_MEMORY() | |||||
| paths = cr_realloc(paths, sizeof(char*) * (psize *= 2)); | |||||
| } | } | ||||
| paths[npaths] = malloc(sizeof(char*) * | |||||
| paths[npaths] = cr_malloc(sizeof(char*) * | |||||
| (strlen(path) + strlen(ROMS_DIR) + 1)); | (strlen(path) + strlen(ROMS_DIR) + 1)); | ||||
| if (!paths[npaths]) | |||||
| OUT_OF_MEMORY() | |||||
| strcpy(paths[npaths], ROMS_DIR "/"); | strcpy(paths[npaths], ROMS_DIR "/"); | ||||
| strcat(paths[npaths], path); | strcat(paths[npaths], path); | ||||
| npaths++; | npaths++; | ||||
| @@ -159,9 +154,7 @@ static int parse_args(Config *config, int argc, char *argv[]) | |||||
| return CONFIG_EXIT_FAILURE; | return CONFIG_EXIT_FAILURE; | ||||
| } | } | ||||
| path = malloc(sizeof(char) * (strlen(arg) + 1)); | |||||
| if (!path) | |||||
| OUT_OF_MEMORY() | |||||
| path = cr_malloc(sizeof(char) * (strlen(arg) + 1)); | |||||
| strcpy(path, arg); | strcpy(path, arg); | ||||
| if (paths_read == 1) { | if (paths_read == 1) { | ||||
| @@ -264,9 +257,7 @@ static void guess_assembler_output_file(Config* config) | |||||
| } | } | ||||
| } while (ptr-- >= src); | } while (ptr-- >= src); | ||||
| config->dst_path = malloc(sizeof(char) * (until_ext + 5)); | |||||
| if (!config->dst_path) | |||||
| OUT_OF_MEMORY() | |||||
| config->dst_path = cr_malloc(sizeof(char) * (until_ext + 5)); | |||||
| strcpy(stpncpy(config->dst_path, src, until_ext), ext); | strcpy(stpncpy(config->dst_path, src, until_ext), ext); | ||||
| } | } | ||||
| @@ -315,14 +306,9 @@ static bool sanity_check(Config* config) | |||||
| */ | */ | ||||
| int config_create(Config** config_ptr, int argc, char* argv[]) | int config_create(Config** config_ptr, int argc, char* argv[]) | ||||
| { | { | ||||
| Config *config; | |||||
| Config *config = cr_malloc(sizeof(Config)); | |||||
| int retval; | int retval; | ||||
| if (!(config = malloc(sizeof(Config)))) { | |||||
| OUT_OF_MEMORY() | |||||
| return CONFIG_EXIT_FAILURE; | |||||
| } | |||||
| config->debug = false; | config->debug = false; | ||||
| config->assemble = false; | config->assemble = false; | ||||
| config->disassemble = false; | config->disassemble = false; | ||||
| @@ -12,17 +12,11 @@ | |||||
| /* | /* | ||||
| Create and return a pointer to a new GameGear object. | Create and return a pointer to a new GameGear object. | ||||
| If memory could not be allocated, OUT_OF_MEMORY() is triggered. | |||||
| */ | */ | ||||
| GameGear* gamegear_create() | GameGear* gamegear_create() | ||||
| { | { | ||||
| GameGear *gg = malloc(sizeof(GameGear)); | |||||
| if (!gg) | |||||
| OUT_OF_MEMORY() | |||||
| if (!mmu_init(&gg->mmu)) | |||||
| OUT_OF_MEMORY() | |||||
| GameGear *gg = cr_malloc(sizeof(GameGear)); | |||||
| mmu_init(&gg->mmu); | |||||
| z80_init(&gg->cpu, &gg->mmu); | z80_init(&gg->cpu, &gg->mmu); | ||||
| gg->powered = false; | gg->powered = false; | ||||
| gg->exc_buffer[0] = '\0'; | gg->exc_buffer[0] = '\0'; | ||||
| @@ -10,27 +10,29 @@ | |||||
| /* Internal usage only */ | /* Internal usage only */ | ||||
| #define LOG_MSG(dest, level, extra, after, ...) { \ | |||||
| #define LOG_MSG_(dest, level, extra, after, ...) { \ | |||||
| fprintf(dest, level ": " __VA_ARGS__); \ | fprintf(dest, level ": " __VA_ARGS__); \ | ||||
| extra; \ | extra; \ | ||||
| fprintf(dest, "\n"); \ | fprintf(dest, "\n"); \ | ||||
| after; \ | after; \ | ||||
| } | } | ||||
| #define PRINT_ERRNO() fprintf(stderr, ": %s", strerror(errno)) | |||||
| #define LOG_ERR_(...) LOG_MSG_(stderr, __VA_ARGS__) | |||||
| #define LOG_OUT_(...) LOG_MSG_(stdout, __VA_ARGS__) | |||||
| #define PRINT_ERRNO_() fprintf(stderr, ": %s", strerror(errno)) | |||||
| /* Public logging macros */ | /* Public logging macros */ | ||||
| #define FATAL(...) LOG_MSG(stderr, "fatal", {}, exit(EXIT_FAILURE), __VA_ARGS__) | |||||
| #define FATAL_ERRNO(...) LOG_MSG(stderr, "fatal", PRINT_ERRNO(), exit(EXIT_FAILURE), __VA_ARGS__) | |||||
| #define ERROR(...) LOG_MSG(stderr, "error", {}, {}, __VA_ARGS__) | |||||
| #define ERROR_ERRNO(...) LOG_MSG(stderr, "error", PRINT_ERRNO(), {}, __VA_ARGS__) | |||||
| #define WARN(...) LOG_MSG(stderr, "warning", {}, {}, __VA_ARGS__) | |||||
| #define WARN_ERRNO(...) LOG_MSG(stderr, "warning", PRINT_ERRNO(), {}, __VA_ARGS__) | |||||
| #define FATAL(...) LOG_ERR_("fatal", {}, exit(EXIT_FAILURE), __VA_ARGS__) | |||||
| #define FATAL_ERRNO(...) LOG_ERR_("fatal", PRINT_ERRNO_(), exit(EXIT_FAILURE), __VA_ARGS__) | |||||
| #define ERROR(...) LOG_ERR_("error", {}, {}, __VA_ARGS__) | |||||
| #define ERROR_ERRNO(...) LOG_ERR_("error", PRINT_ERRNO_(), {}, __VA_ARGS__) | |||||
| #define WARN(...) LOG_ERR_("warning", {}, {}, __VA_ARGS__) | |||||
| #define WARN_ERRNO(...) LOG_ERR_("warning", PRINT_ERRNO_(), {}, __VA_ARGS__) | |||||
| #ifdef DEBUG_MODE | #ifdef DEBUG_MODE | ||||
| #define DEBUG(...) LOG_MSG(stdout, "[DEBUG]", {}, {}, __VA_ARGS__) | |||||
| #define DEBUG(...) LOG_OUT_("[DEBUG]", {}, {}, __VA_ARGS__) | |||||
| #else | #else | ||||
| #define DEBUG(...) {} | #define DEBUG(...) {} | ||||
| #endif | #endif | ||||
| #define OUT_OF_MEMORY() FATAL("couldn't allocate enough memory") | |||||
| @@ -5,27 +5,21 @@ | |||||
| #include <string.h> | #include <string.h> | ||||
| #include "logging.h" | #include "logging.h" | ||||
| #include "util.h" | |||||
| #include "z80.h" | #include "z80.h" | ||||
| /* | /* | ||||
| Initialize a MMU object. This must be called before using the MMU. | Initialize a MMU object. This must be called before using the MMU. | ||||
| Return true if initialization was successful, or false if the required | |||||
| amount of memory could not be allocated. | |||||
| */ | */ | ||||
| bool mmu_init(MMU *mmu) | |||||
| void mmu_init(MMU *mmu) | |||||
| { | { | ||||
| mmu->system_ram = malloc(sizeof(uint8_t) * MMU_SYSTEM_RAM_SIZE); | |||||
| if (!mmu->system_ram) | |||||
| return false; | |||||
| mmu->system_ram = cr_malloc(sizeof(uint8_t) * MMU_SYSTEM_RAM_SIZE); | |||||
| for (size_t slot = 0; slot < MMU_NUM_SLOTS; slot++) | for (size_t slot = 0; slot < MMU_NUM_SLOTS; slot++) | ||||
| mmu->map_slots[slot] = NULL; | mmu->map_slots[slot] = NULL; | ||||
| for (size_t bank = 0; bank < MMU_NUM_ROM_BANKS; bank++) | for (size_t bank = 0; bank < MMU_NUM_ROM_BANKS; bank++) | ||||
| mmu->rom_banks[bank] = NULL; | mmu->rom_banks[bank] = NULL; | ||||
| return true; | |||||
| } | } | ||||
| /* | /* | ||||
| @@ -22,7 +22,7 @@ typedef struct { | |||||
| /* Functions */ | /* Functions */ | ||||
| bool mmu_init(MMU*); | |||||
| void mmu_init(MMU*); | |||||
| void mmu_free(MMU*); | void mmu_free(MMU*); | ||||
| void mmu_load_rom(MMU*, const uint8_t*, size_t); | void mmu_load_rom(MMU*, const uint8_t*, size_t); | ||||
| void mmu_power(MMU*); | void mmu_power(MMU*); | ||||
| @@ -169,8 +169,7 @@ const char* rom_open(ROM **rom_ptr, const char *path) | |||||
| return (st.st_mode & S_IFDIR) ? rom_err_isdir : rom_err_notfile; | return (st.st_mode & S_IFDIR) ? rom_err_isdir : rom_err_notfile; | ||||
| } | } | ||||
| if (!(rom = malloc(sizeof(ROM)))) | |||||
| OUT_OF_MEMORY() | |||||
| rom = cr_malloc(sizeof(ROM)); | |||||
| // Set defaults: | // Set defaults: | ||||
| rom->name = NULL; | rom->name = NULL; | ||||
| @@ -183,8 +182,7 @@ const char* rom_open(ROM **rom_ptr, const char *path) | |||||
| rom->region_code = 0; | rom->region_code = 0; | ||||
| // Set rom->name: | // Set rom->name: | ||||
| if (!(rom->name = malloc(sizeof(char) * (strlen(path) + 1)))) | |||||
| OUT_OF_MEMORY() | |||||
| rom->name = cr_malloc(sizeof(char) * (strlen(path) + 1)); | |||||
| strcpy(rom->name, path); | strcpy(rom->name, path); | ||||
| DEBUG("Loading ROM %s:", rom->name) | DEBUG("Loading ROM %s:", rom->name) | ||||
| @@ -198,8 +196,7 @@ const char* rom_open(ROM **rom_ptr, const char *path) | |||||
| rom->size = st.st_size; | rom->size = st.st_size; | ||||
| // Set rom->data: | // Set rom->data: | ||||
| if (!(rom->data = malloc(sizeof(uint8_t) * st.st_size))) | |||||
| OUT_OF_MEMORY() | |||||
| rom->data = cr_malloc(sizeof(uint8_t) * st.st_size); | |||||
| if (!(fread(rom->data, st.st_size, 1, fp))) { | if (!(fread(rom->data, st.st_size, 1, fp))) { | ||||
| rom_close(rom); | rom_close(rom); | ||||
| fclose(fp); | fclose(fp); | ||||
| @@ -6,6 +6,8 @@ | |||||
| #include <stdbool.h> | #include <stdbool.h> | ||||
| #include <stdint.h> | #include <stdint.h> | ||||
| #include "util_alloc.h" | |||||
| #define INVALID_SIZE_CODE 0x8 | #define INVALID_SIZE_CODE 0x8 | ||||
| /* Functions */ | /* Functions */ | ||||
| @@ -0,0 +1,40 @@ | |||||
| /* Copyright (C) 2014-2015 Ben Kurtovic <ben.kurtovic@gmail.com> | |||||
| Released under the terms of the MIT License. See LICENSE for details. */ | |||||
| #pragma once | |||||
| #include <stddef.h> | |||||
| #include <stdlib.h> | |||||
| #include <string.h> | |||||
| #include "logging.h" | |||||
| #define OUT_OF_MEMORY() FATAL("couldn't allocate enough memory") | |||||
| #define OOM_GUARD_(type, call) \ | |||||
| type ptr = call; \ | |||||
| if (!ptr) \ | |||||
| OUT_OF_MEMORY() \ | |||||
| return ptr; | |||||
| #define OOM_GUARD_FUNC_1_(ret_type, func, arg_type) \ | |||||
| static inline ret_type cr_##func(arg_type arg1) { \ | |||||
| OOM_GUARD_(ret_type, func(arg1)) \ | |||||
| } | |||||
| #define OOM_GUARD_FUNC_2_(ret_type, func, arg1_type, arg2_type) \ | |||||
| static inline ret_type cr_##func(arg1_type arg1, arg2_type arg2) { \ | |||||
| OOM_GUARD_(ret_type, func(arg1, arg2)) \ | |||||
| } | |||||
| /* Functions */ | |||||
| OOM_GUARD_FUNC_1_(void*, malloc, size_t) // cr_malloc | |||||
| OOM_GUARD_FUNC_2_(void*, calloc, size_t, size_t) // cr_calloc | |||||
| OOM_GUARD_FUNC_2_(void*, realloc, void*, size_t) // cr_realloc | |||||
| OOM_GUARD_FUNC_1_(char*, strdup, const char*) // cr_strdup | |||||
| OOM_GUARD_FUNC_2_(char*, strndup, const char*, size_t) // cr_strndup | |||||
| #undef OOM_GUARD_FUNC2_ | |||||
| #undef OOM_GUARD_FUNC1_ | |||||
| #undef OOM_GUARD_ | |||||