@@ -201,10 +201,7 @@ size_t assemble(const LineBuffer *source, uint8_t **binary_ptr, ErrorInfo **ei_p | |||
if ((error_info = resolve_symbols(&state))) | |||
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); | |||
*binary_ptr = binary; | |||
retval = state.rom_size; | |||
@@ -6,7 +6,7 @@ | |||
#include "errors.h" | |||
#include "state.h" | |||
#include "../assembler.h" | |||
#include "../logging.h" | |||
#include "../util.h" | |||
/* Error strings */ | |||
@@ -82,27 +82,20 @@ struct ErrorInfo { | |||
*/ | |||
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; | |||
size_t length = line->original->length; | |||
if (!(el->data = malloc(sizeof(char) * length))) | |||
OUT_OF_MEMORY() | |||
// Ignore spaces at beginning: | |||
while (length > 0 && (*source == ' ' || *source == '\t')) | |||
source++, length--; | |||
el->data = cr_malloc(sizeof(char) * length); | |||
memcpy(el->data, source, length); | |||
el->length = length; | |||
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; | |||
return el; | |||
} | |||
@@ -119,10 +112,7 @@ static ASMErrorLine* create_error_line(const ASMLine *line) | |||
ErrorInfo* error_info_create( | |||
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->desc = err_desc; | |||
einfo->line = line ? create_error_line(line) : NULL; | |||
@@ -5,7 +5,7 @@ | |||
#include <string.h> | |||
#include "hash_table.h" | |||
#include "../logging.h" | |||
#include "../util.h" | |||
#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( | |||
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->key_offset = key_offset; | |||
table->next_offset = next_offset; | |||
@@ -7,7 +7,7 @@ | |||
#include "instructions.h" | |||
#include "inst_args.h" | |||
#include "parse_util.h" | |||
#include "../logging.h" | |||
#include "../util.h" | |||
/* Helper macros for get_inst_parser() */ | |||
@@ -26,8 +26,7 @@ | |||
#define INST_ALLOC_(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_SET1_(b1) INST_SET_(0, b1) | |||
@@ -55,7 +54,7 @@ static ASMErrorDesc parse_inst_##mnemonic( \ | |||
#define INST_TAKES_NO_ARGS \ | |||
if (ap_info.arg) \ | |||
INST_ERROR(TOO_MANY_ARGS) \ | |||
INST_ERROR(TOO_MANY_ARGS) | |||
#define INST_TAKES_ARGS(lo, hi) \ | |||
if (!ap_info.arg) \ | |||
@@ -104,9 +103,7 @@ static ASMErrorDesc parse_inst_##mnemonic( \ | |||
} | |||
#define INST_RETURN_WITH_SYMBOL(len, label, ...) { \ | |||
*symbol = strdup(label); \ | |||
if (!(*symbol)) \ | |||
OUT_OF_MEMORY() \ | |||
*symbol = cr_strdup(label); \ | |||
INST_ALLOC_(len) \ | |||
INST_FILL_BYTES_(len - 2, __VA_ARGS__) \ | |||
return ED_NONE; \ | |||
@@ -9,6 +9,7 @@ | |||
#include "io.h" | |||
#include "../logging.h" | |||
#include "../util.h" | |||
/* | |||
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; | |||
} | |||
LineBuffer *source = malloc(sizeof(LineBuffer)); | |||
if (!source) | |||
OUT_OF_MEMORY() | |||
LineBuffer *source = cr_malloc(sizeof(LineBuffer)); | |||
source->lines = NULL; | |||
source->filename = strdup(path); | |||
if (!source->filename) | |||
OUT_OF_MEMORY() | |||
source->filename = cr_strdup(path); | |||
Line dummy = {.next = NULL}; | |||
Line *line, *prev = &dummy; | |||
@@ -90,10 +86,7 @@ LineBuffer* read_source_file(const char *path, bool print_errors) | |||
return NULL; | |||
} | |||
line = malloc(sizeof(Line)); | |||
if (!line) | |||
OUT_OF_MEMORY() | |||
line = cr_malloc(sizeof(Line)); | |||
line->data = data; | |||
line->length = feof(fp) ? len : (len - 1); | |||
line->lineno = lineno++; | |||
@@ -7,7 +7,6 @@ | |||
#include "parse_util.h" | |||
#include "directives.h" | |||
#include "../logging.h" | |||
#include "../util.h" | |||
#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; | |||
*length = size - 2; | |||
*result = malloc(sizeof(char) * (*length)); | |||
if (!*result) | |||
OUT_OF_MEMORY() | |||
*result = cr_malloc(sizeof(char) * (*length)); | |||
memcpy(*result, arg + 1, *length); | |||
return true; | |||
} | |||
@@ -217,9 +214,7 @@ bool parse_bytes(uint8_t **result, size_t *length, const char *arg, ssize_t size | |||
} | |||
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; | |||
if (arg < end - 1 && *arg == ',' && *(arg + 1) == ' ') | |||
@@ -121,14 +121,8 @@ static size_t read_labels( | |||
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); | |||
line->length = i - start + 1; | |||
line->is_label = true; | |||
@@ -160,10 +154,7 @@ static ASMLine* normalize_line(const char *source, size_t length) | |||
source += 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; | |||
bool has_content = false, space_pending = false, in_string = false; | |||
for (si = di = 0; si < length; si++) { | |||
@@ -206,14 +197,8 @@ static ASMLine* normalize_line(const char *source, size_t length) | |||
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->length = di; | |||
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 | |||
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))) | |||
goto error; | |||
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)) | |||
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 | |||
snprintf(path, maxlen, "%s/%.*s", dirname(dup), (int) baselen, base); | |||
@@ -330,10 +311,7 @@ static ErrorInfo* build_asm_lines( | |||
goto error; | |||
} | |||
ASMInclude *include = malloc(sizeof(ASMInclude)); | |||
if (!include) | |||
OUT_OF_MEMORY() | |||
ASMInclude *include = cr_malloc(sizeof(ASMInclude)); | |||
include->lines = incbuffer; | |||
include->next = *includes; | |||
*includes = include; | |||
@@ -9,7 +9,6 @@ | |||
#include "instructions.h" | |||
#include "inst_args.h" | |||
#include "parse_util.h" | |||
#include "../logging.h" | |||
#include "../mmu.h" | |||
#include "../rom.h" | |||
#include "../util.h" | |||
@@ -63,12 +62,8 @@ static void init_layout_info(ASMLayoutInfo *li, AssemblerState *state) | |||
li->origin = NULL; | |||
li->bank = 0; | |||
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++) | |||
li->overlap_table[state->header.offset + i] = &header_sentinel; | |||
@@ -104,10 +99,7 @@ static ErrorInfo* add_label_to_table( | |||
if (argparse_condition(&cond, info)) | |||
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); | |||
if (current) { | |||
ErrorInfo *ei = error_info_create(line, ET_SYMBOL, ED_SYM_DUPE_LABELS); | |||
@@ -116,10 +108,7 @@ static ErrorInfo* add_label_to_table( | |||
return ei; | |||
} | |||
ASMSymbol *label = malloc(sizeof(ASMSymbol)); | |||
if (!label) | |||
OUT_OF_MEMORY() | |||
ASMSymbol *label = cr_malloc(sizeof(ASMSymbol)); | |||
label->offset = map_into_slot(offset, | |||
(slot >= 0) ? slot : default_bank_slot(offset / MMU_ROM_BANK_SIZE)); | |||
label->symbol = symbol; | |||
@@ -169,13 +158,8 @@ static ErrorInfo* handle_define_directive( | |||
if (!argparse_immediate(&imm, info)) | |||
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->line = line; | |||
asm_deftable_insert(deftab, define); | |||
@@ -285,9 +269,7 @@ static bool parse_space( | |||
} | |||
*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); | |||
free(bytes); | |||
return true; | |||
@@ -328,10 +310,7 @@ static ErrorInfo* parse_data( | |||
const char *arg = line->data + 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->next = NULL; | |||
@@ -386,10 +365,7 @@ static ErrorInfo* parse_instruction( | |||
if (edesc != ED_NONE) | |||
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.length = length; | |||
inst->bytes = bytes; | |||
@@ -10,6 +10,7 @@ | |||
#include "config.h" | |||
#include "logging.h" | |||
#include "util.h" | |||
#include "version.h" | |||
/* | |||
@@ -73,21 +74,15 @@ static int get_rom_paths(char ***path_ptr) | |||
dirp = opendir(ROMS_DIR); | |||
if (dirp) { | |||
paths = malloc(sizeof(char*) * psize); | |||
if (!paths) | |||
OUT_OF_MEMORY() | |||
paths = cr_malloc(sizeof(char*) * psize); | |||
while ((entry = readdir(dirp))) { | |||
path = entry->d_name; | |||
if (ends_with(path, ".gg") || ends_with(path, ".bin")) { | |||
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)); | |||
if (!paths[npaths]) | |||
OUT_OF_MEMORY() | |||
strcpy(paths[npaths], ROMS_DIR "/"); | |||
strcat(paths[npaths], path); | |||
npaths++; | |||
@@ -159,9 +154,7 @@ static int parse_args(Config *config, int argc, char *argv[]) | |||
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); | |||
if (paths_read == 1) { | |||
@@ -264,9 +257,7 @@ static void guess_assembler_output_file(Config* config) | |||
} | |||
} 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); | |||
} | |||
@@ -315,14 +306,9 @@ static bool sanity_check(Config* config) | |||
*/ | |||
int config_create(Config** config_ptr, int argc, char* argv[]) | |||
{ | |||
Config *config; | |||
Config *config = cr_malloc(sizeof(Config)); | |||
int retval; | |||
if (!(config = malloc(sizeof(Config)))) { | |||
OUT_OF_MEMORY() | |||
return CONFIG_EXIT_FAILURE; | |||
} | |||
config->debug = false; | |||
config->assemble = false; | |||
config->disassemble = false; | |||
@@ -12,17 +12,11 @@ | |||
/* | |||
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 *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); | |||
gg->powered = false; | |||
gg->exc_buffer[0] = '\0'; | |||
@@ -10,27 +10,29 @@ | |||
/* Internal usage only */ | |||
#define LOG_MSG(dest, level, extra, after, ...) { \ | |||
#define LOG_MSG_(dest, level, extra, after, ...) { \ | |||
fprintf(dest, level ": " __VA_ARGS__); \ | |||
extra; \ | |||
fprintf(dest, "\n"); \ | |||
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 */ | |||
#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 | |||
#define DEBUG(...) LOG_MSG(stdout, "[DEBUG]", {}, {}, __VA_ARGS__) | |||
#define DEBUG(...) LOG_OUT_("[DEBUG]", {}, {}, __VA_ARGS__) | |||
#else | |||
#define DEBUG(...) {} | |||
#endif | |||
#define OUT_OF_MEMORY() FATAL("couldn't allocate enough memory") |
@@ -5,27 +5,21 @@ | |||
#include <string.h> | |||
#include "logging.h" | |||
#include "util.h" | |||
#include "z80.h" | |||
/* | |||
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++) | |||
mmu->map_slots[slot] = NULL; | |||
for (size_t bank = 0; bank < MMU_NUM_ROM_BANKS; bank++) | |||
mmu->rom_banks[bank] = NULL; | |||
return true; | |||
} | |||
/* | |||
@@ -22,7 +22,7 @@ typedef struct { | |||
/* Functions */ | |||
bool mmu_init(MMU*); | |||
void mmu_init(MMU*); | |||
void mmu_free(MMU*); | |||
void mmu_load_rom(MMU*, const uint8_t*, size_t); | |||
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; | |||
} | |||
if (!(rom = malloc(sizeof(ROM)))) | |||
OUT_OF_MEMORY() | |||
rom = cr_malloc(sizeof(ROM)); | |||
// Set defaults: | |||
rom->name = NULL; | |||
@@ -183,8 +182,7 @@ const char* rom_open(ROM **rom_ptr, const char *path) | |||
rom->region_code = 0; | |||
// 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); | |||
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; | |||
// 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))) { | |||
rom_close(rom); | |||
fclose(fp); | |||
@@ -6,6 +6,8 @@ | |||
#include <stdbool.h> | |||
#include <stdint.h> | |||
#include "util_alloc.h" | |||
#define INVALID_SIZE_CODE 0x8 | |||
/* 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_ |