@@ -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_ |